IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 代理模式及AOP整理 -> 正文阅读

[Java知识库]代理模式及AOP整理

代理模式

这是SpringAOP的底层!

好处:

1.使真实角色的操作更加纯粹,不用去关注一些公共业务

2.公共业务交给代理角色,实现了业务的分工

3.公共业务发生扩展的时候,方便集中管理

缺点:

一个真实角色就会产生一个代理角色;代码量会翻倍,开发效率会变低(解决办法动态代理

?

代理模式的分类:

1.静态代理

【角色分析】

抽象的角色:一般使用接口或者抽象类来解决

真实角色:被代理的角色

代理角色:代理真实角色,代理后,一般会做一些附属操作

客户:访问代理对象的人!

//接口/租房的接口
public interface Rent {
 ? ?public void rent();
}
//真实角色
//房东 
public class Host implements Rent {
 ? ?@Override
 ? ?public void rent() {
 ? ? ? ?System.out.println("房东要出租房屋!");
 ?  }
}
//代理角色
//代理角色 要 实现方法
public class Proxy implements Rent{
 ? ?private Host host;
 ? ?public Proxy() {
 ?  }
 ? ?public Proxy(Host host) {
 ? ? ? ?this.host = host;
 ?  }
 ? ?@Override
 ? ?public void rent() {
 ? ? ? ?host.rent();
 ? ? ? ?seeHouse();
 ? ? ? ?hetong();
 ? ? ? ?fare();
 ?  }
 ? ?//看房
 ? ?public void seeHouse(){
 ? ? ? ?System.out.println("中介可以带你看房");
 ?  }
 ? ?//收中介费
 ? ?public void fare(){
 ? ? ? ?System.out.println("中介要收中介费");
 ?  }
 ? ?//签合同
 ? ?public void hetong(){
 ? ? ? ?System.out.println("中介跟你签合同");
 ?  }
}
//客户端访问代理角色
//租客
public class Client {
 ? ?public static void main(String[] args) {
 ? ? ? ?//房东要出租房屋
 ? ? ? ?Host host = new Host();
 ? ? ? ?//代理 帮房东出租房屋 ,代理角色一般会有一些附属操作
 ? ? ? ?Proxy proxy = new Proxy(host);
 ? ? ? ?//直接面向代理租房
 ? ? ? ?proxy.rent();
 ?  }
}
//例子二
//业务接口
public interface UserService {
 ? ?public void add();
 ? ?public void delete();
 ? ?public void update();
 ? ?public void query();
}
//实现类 真实对象
public class UserServiceImpl implements UserService{
 ? ?@Override
 ? ?public void add() {
 ? ? ? ?System.out.println("增加了用户");
 ?  }
?
 ? ?@Override
 ? ?public void delete() {
 ? ? ? ?System.out.println("删除了用户");
 ?  }
  ...
 ? ?//代理对象 增加业务
 ? ?public class UserServiceProxy implements UserService{
 ? ?UserServiceImpl userService;
 ? //用set方式实现注入
 ? ?public void setUserService(UserServiceImpl userService) {
 ? ? ? ?this.userService = userService;
 ?  }
 ? ?@Override
 ? ?public void add() {
 ? ? ?log("add");
 ? ? ? ?userService.add();
 ?  }
 ? ?@Override
 ? ?public void delete() {
 ? ? ? ?log("delete");
 ? ? ? ?userService.delete();
 ?  }
 ? ? ? //增加日志方法
 ? ?public void log(String msg){
 ? ? ? ?System.out.println("[Debug] 使用了"+msg+"方法");
 ?  }
 ? ?  ...
 ? ? ? ?//客户端访问
public class Client {
 ? ?public static void main(String[] args) {
 ? ? ? ?UserServiceImpl userService=new UserServiceImpl();
 ? ? ? ?UserServiceProxy proxy = new UserServiceProxy();
 ? ? ? ?//要代理谁?
 ? ? ? ?proxy.setUserService(userService);
 ? ? ? ?proxy.add();
 ?  }
}

2.动态代理(底层都是反射)

动态代理和静态代理角色一致,动态代理的代理类 是动态生成的,不是我们直接写好的!

动态代理分为三大类:

基于接口:【JDK动态代理】

基于类:【cglib】

java字节码实现:【javassist】

两个类

Proxy :代理 提供了创建动态代理类和实例的静态方法

InvocationHandler(反射包下得接口) : 调用处理程序并返回结果

//租房的接口
public interface Rent {
 ? ?public void rent();
}
//房东 真实角色
public class Host implements Rent {
 ? ?@Override
 ? ?public void rent() {
 ? ? ? ?System.out.println("房东要出租房屋!");
 ?  }
}
?
//我们用这个类自动生成代理类 InvocationHandler 调用处理程序并返回结果
public class ProxyInvocationHandler implements InvocationHandler {
 ? ?//被代理的接口
 ? ?private Rent rent;
?
 ? ?public void setRent(Rent rent) {
 ? ? ? ?this.rent = rent;
 ?  }
 ? ?//生成得到 代理类
 ? ?public Object getProxy(){
 ? ? ? ?return Proxy.newProxyInstance(this.getClass().getClassLoader(),
 ? ? ? ? ? ? ? ?rent.getClass().getInterfaces(), ?this);
 ?  }
 ? ?//处理代理实例,并返回结果 调用代理类的一些执行方法
 ? ?@Override
 ? ?public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 ? ? ? //执行接口上的方法
 ? ? ? ?//动态代理的本质,就是使用反射机制实现
 ? ? ? ?seeHouse();
 ? ? ? ?Object result = method.invoke(rent, args);
 ? ? ? ?fare();
 ? ? ? ?return result;
 ?  }
 ? ?public void seeHouse(){
 ? ? ? ?System.out.println("中介带看房");
 ?  }
 ? ?public void fare(){
 ? ? ? ?System.out.println("收中介费");
 ?  }
}
?
public class Client {
 ? ?public static void main(String[] args) {
 ? ? ? ?//真实角色
 ? ? ? ?Host host=new Host();
 ? ? ? ?//代理角色 暂时没有
 ? ? ? ?ProxyInvocationHandler pih = new ProxyInvocationHandler();
 ? ? ? ?//通过调用程序处理角色 来处理我们要调用的接口对象!
 ? ? ? ?pih.setRent(host);
 ? ? ? ?//这里的proxy就是动态生成的,我们并没有写
 ? ? ? ?Rent proxy = (Rent) pih.getProxy();
 ? ? ? ?proxy.rent();
?
 ?  }
}

抽取共性:

//我们用这个类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
 ? ?//被代理的接口
 ? ?private Object target;
?
 ? ?public void setTarget(Object target) {
 ? ? ? ?this.target = target;
 ?  }
 ? ?//生成得到 代理类
 ? ?public Object getProxy(){
 ? ? ? ?return Proxy.newProxyInstance(this.getClass().getClassLoader(),
 ? ? ? ? ? ? ? ?target.getClass().getInterfaces(), ?this);
 ?  }
 ? ?//处理代理实例,并返回结果,调用代理类的一些执行方法
 ? ?@Override
 ? ?public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 ? ? ? //执行接口上的方法
 ? ? ? ?//动态代理的本质,就是使用反射机制实现
 ? ? ? ?log(method.getName());
 ? ? ? ?Object result = method.invoke(target, args);
 ? ? ? ?return result;
 ?  }
?
 ? ?public void log(String msg){
 ? ? ? ?System.out.println("执行了"+msg+"方法");
 ?  }
}
//调用
public class Client {
 ? ?public static void main(String[] args) {
 ? ? ? ?//真实角色
 ? ? ? ?UserServiceImpl userService=new UserServiceImpl();
 ? ? ? ?//代理角色 不存在
 ? ? ? ?ProxyInvocationHandler pih = new ProxyInvocationHandler();
 ? ? ? ?//设置要代理的对象
 ? ? ? ?pih.setTarget(userService);
 ? ? ? ?//动态生成代理类
 ? ? ? ?UserService proxy =(UserService) pih.getProxy();
?
 ? ? ? ?proxy.add();
?
 ?  }
}

动态代理的好处:

1.使真实角色的操作更加纯粹,不用去关注一些公共业务

2.公共业务交给代理角色,实现了业务的分工

3.公共业务发生扩展的时候,方便集中管理

4.一个动态代理类代理的是一个接口,一般对应一类业务

5.一个动态代理类可以代理多个类,只要是实现了同一个接口即可!


AOP

?

?

spring实现AOP 需要加织入的依赖
<dependency>
 ? ? ? ? ? ?<groupId>org.aspectj</groupId>
 ? ? ? ? ? ?<artifactId>aspectjweaver</artifactId>
 ? ? ? ? ? ?<version>1.9.4</version>
 ? ? ? ?</dependency>

方式一:使用Spring的API接口实现AOP 原生api接口

//业务接口
public interface UserService {
 ? ?public void add();
 ? ?public void delete();
 ? ?public void update();
 ? ?public void select();
}
//实现类
public class UserServiceImpl implements UserService{
 ? ?@Override
 ? ?public void add() { System.out.println("增加一个用户"); }
 ? ?@Override
 ? ?public void delete() { System.out.println("删除一个用户"); }
 ? ?@Override
 ? ?public void update() { System.out.println("更新一个用户"); }
 ? ?@Override
 ? ?public void select() { System.out.println("查询一个用户"); }
}
//需要增加的内容
//直接使用Spring的API
public class Log implements MethodBeforeAdvice {
 ? ?/* method: 要执行的目标对象的方法
 ? ?* args : 参数
 ? ?* target:目标对象*/
 ? ?@Override
 ? ?public void before(Method method, Object[] args, Object target) throws Throwable {
 ? ? ? ?System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
 ?  }
}
?
public class AfterLog implements AfterReturningAdvice {
 ? ?//returnValue 返回值
 ? ?@Override
 ? ?public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
 ? ? ? ?System.out.println("执行了"+method.getName()+"方法,返回结果为"+returnValue);
 ?  }
}
?

用最原始方法配置xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 ? ? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 ? ? ? xmlns:aop="http://www.springframework.org/schema/aop"
 ? ? ? xsi:schemaLocation="http://www.springframework.org/schema/beans
 ? ? ? ?https://www.springframework.org/schema/beans/spring-beans.xsd
 ? ? ? ?http://www.springframework.org/schema/aop
 ? ? ? ?https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册bean-->
 ? ?<bean id="userService" class="com.xie.service.UserServiceImpl"/>
 ? ?<bean id="log" class="com.xie.log.Log"/>
 ? ?<bean id="afterlog" class="com.xie.log.AfterLog"/>
<!--方式一:使用原生Spring api接口-->
<!--配置aop 导入aop的约束-->
<aop:config>
<!--切入点 我们在哪执行  expression表达式 execution(要执行的位置! * * * * *)-->
 ? ?<aop:pointcut id="pointcut" expression="execution(* com.xie.service.UserServiceImpl.*(..))"/>
<!--执行环绕增强-->
 ? ?<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
 ? ?<aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>
</aop:config>
</beans>

测试类:

public class MyTest {
 ? ?public static void main(String[] args) {
 ? ? ? ?ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
 ? ? ? ?//动态代理代理的是接口 所以这里不能用实现类!
 ? ? ? ?UserService userService = context.getBean("userService", UserService.class);
 ? ? ? ?userService.add();
 ?  }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 10:41:48  更:2022-01-24 10:43:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:01:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码