代理实现aop以及代理工厂实现增强
一、静态代理实现
1.接口(抽象主题)

2.接口的实现类(真实主题)

3.代理类(代理主题)

4.测试类:
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
ProxySubject proxySubject =(ProxySubject) context.getBean("proxySubject");
proxySubject.doSome();
二、JDK动态代理
JDK动态代理所用到的代理类在程序调用到代理类对象时才由JVM真正创建,JVM根据传进来的 业务实现类对象 以及 方法名 ,动态地创建了一个代理类的class文件并被字节码引擎执行,然后通过该代理类对象进行方法调用。
1.抽象主题,真实主题与上面一致
2.动态代理类
package com.cmy.handler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class DoSomeBeanFactory implements InvocationHandler {
private Object target;//这其实业务实现类对象,用来调用具体的业务方法 public Object bind(Object target) {
this.target = target; //接收业务实现类对象参数 //通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用
//创建代理对象时,需要传递该业务类的类加载器(用来获取业务实现类的元数据,在包装方法是调用真正的业务方法)、接口、handler实现类
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置=====");
//调用真正的业务方法
Object result = method.invoke(target, args);
System.out.println("后置=====");
return result;
}
}
3.测试类
public class ProxyDemo {
public static void main(String[] args) {
//创建业务类对象
Subject subject=new ReallySubject();
//创建代理对象
DoSomeBeanFactory factory=new DoSomeBeanFactory();
//调用bind方法获取代理对象
Subject proxy = (Subject)factory.bind(subject);
//调用目标函数
proxy.say();
}
}
三、Cglib动态代理
cglib是针对类来实现代理的,原理是对指定的业务类生成一个子类,并覆盖其中业务方法实现代理。因为采用的是继承,所以不能对final修饰的类进行代理。
新建代理类
package com.cmy.handler;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method; public class DoSomeBeanCGlib implements MethodInterceptor{
private Object target;//业务类对象,供代理方法中进行真正的业务方法调用 //相当于JDK动态代理中的绑定
public Object getInstance(Object target) {
this.target = target; //给业务对象赋值
Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
enhancer.setSuperclass(this.target.getClass()); //为加强器指 //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实 现intercept()方法进行拦
enhancer.setCallback(this);
// 创建动态代理类对象并返回
return enhancer.create();
} @Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("预处理——————");
methodProxy.invokeSuper(o, objects); //调用业务类(父类中)的方法
System.out.println("调用后操作——————");
return null;
}
}
四.代理工厂增强
借助Spring IOC的机制,为ProxyFactory代理工厂的属性实现依赖注入,这样做的优点是可配置型高,易用性好。
1.创建抽象主题
public interface ProService {
public void doSome();
}
2.创建真实主题
public class ProServiceImpl implements ProService {
@Override
public void doSome() {
System.out.println("123");
}
}
3.创建增强类
这里实现了前置增强的接口,用前置增强来模拟增强
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class BeaforeProxy implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("前置");
}
}
4.配置大配置文件
<!--注入bean-->
<bean id="proService" class="cn.spring.proxyFactory.ProServiceImpl"></bean>
<!--切面-->
<bean id="beaforeProxy" class="cn.spring.proxyFactory.BeaforeProxy"></bean>
<!--代理工厂实现增强-->
<bean id="ProFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--将增强和业务织入到一起-->
<property name="target" ref="proService"></property>
<!--拦截增强类-->
<property name="interceptorNames" value="beaforeProxy"></property>
</bean>
5.测试
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
ProService proService =(ProService) context.getBean("ProFactory");
proService.doSome();
}
6.结果

值得注意的是这种代理工场的代理方式默认为Jdk,如果不存在接口,则使用Cglib代理,这个可以通过断点直观看出,若想规定使用,则可以在大配置文件代理工厂的节点下中设置
<!--更换代理方式 默认值为false jdk动态代理,当没有接口时,自动改成cglib-->
<property name="proxyTargetClass" value="true"></property>

代理实现aop以及代理工厂实现增强的更多相关文章
- Spring-构造注入&注解注入&代理模式&AOP
1. 课程介绍 1. 依赖注入;(掌握) 2. XML自动注入;(掌握) 3. 全注解配置;(掌握) 4. 代理模式;(掌握) 5. AOP;(掌握) 依赖注入;(掌握) 2.1. 构 ...
- Spring——代理工厂实现增强
借助Spring IOC的机制,为ProxyFactory代理工厂的属性实现依赖注入,这样做的优点是可配置型高,易用性好. 1.创建抽象主题 public interface ProService { ...
- spring aop 的代理工厂
参考 https://docs.spring.io/spring/docs/4.3.11.RELEASE/spring-framework-reference/htmlsingle/#aop-unde ...
- AOP动态代理解析4-代理的创建
做完了增强器的获取后就可以进行代理的创建了 AnnotationAwareAspectJAutoProxyCreator->postProcessAfterInitialization-> ...
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码 ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
- Spring AOP(基于代理类的AOP实现)
#基于代理类的AOP实现:step1: 1 package com.sjl.factorybean; /**切面类*/ import org.aopalliance.intercept.MethodI ...
- Java 动态代理及AOP实现机制
AOP实现机制http://www.iteye.com/topic/1116696 AOP: (Aspect Oriented Programming) 面向切面编程AOP包括切面(aspect).通 ...
- Java-JDK动态代理(AOP)使用及实现原理分析
Java-JDK动态代理(AOP)使用及实现原理分析 第一章:代理的介绍 介绍:我们需要掌握的程度 动态代理(理解) 基于反射机制 掌握的程度: 1.什么是动态代理? 2.动态代理能够做什么? 后面我 ...
随机推荐
- mysql错误问题处理
问题1.mysql 黑窗口出现错误 无法启动此应用程序 ,计算机中丢失MSVCP120.DLL,请重新安装 因为是从虚拟机上安装的新的系统,所以dos窗口输入mysql -v的时候出现了上述的错误,之 ...
- (一)tensorflow-gpu2.0学习笔记之开篇(cpu和gpu计算速度比较)
摘要: 1.以动态图形式计算一个简单的加法 2.cpu和gpu计算力比较(包括如何指定cpu和gpu) 3.关于gpu版本的tensorflow安装问题,可以参考另一篇博文:https://www.c ...
- 【Go语言系列】第三方框架和库——GIN:GIN介绍
1.Gin 是什么? Gin 是一个用 Go (Golang) 编写的 HTTP web 框架. 它是一个类似于 martini 但拥有更好性能的 API 框架, 由于 httprouter,速度提高 ...
- springmvc基于java配置的实现
该案例的github地址:https://github.com/zhouyanger/demo/tree/master/springmvc-noxml-demo 1.介绍 之前搭建SpringMvc项 ...
- photoshop下载(ps)
https://pan.baidu.com/s/1bNrUod2n1VqsA7Fr9RHtsg
- Linux :ls 命令
常用命令: ls:列出当前路径下的文件和目录 ls -a:列出当前路径下的所有文件和目录(包括隐藏文件和目录) ls -l:以列表方式显示文件或目录的详细信息 ls -al:可以结合使用 ls xxx ...
- werkeug的WSGI服务器解析
werkeug的WSGI服务器解析 1. WSGI 1.1. wsgi与flask flask默认的wsgi引用自wekurg 声明app:FLASK对象 app.run() run_ ...
- 吴裕雄--天生自然Numpy库学习笔记:NumPy 数组属性
NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推. 在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(di ...
- 对于java中反编译命令的使用以及Integer包装类的查看
Integer是基于int的包装类 我们可以用测试代码来看看Integer类是如何实现装箱和拆箱的 public class BoxAndUnbox { /** * @param args */ pu ...
- vue 组件,以及组件的复用
有时候代码的某一模块可能会经常使用到,那么完全可以把这一模块抽取出来,封装为一个组件,哪里需要用到的时候只需把模块调用即可 .参考vue官方 https://cn.vuejs.org/v2/guide ...