Spring-Aop的两种代理方式


Spring-Aop两种代理方式:

1、JDK动态代理:用于目标类实现了接口;

2、Cglib动态代理:用于目标类没有实现接口;

spring会依据目标类是否实现接口来选择使用哪种代理方式(目标类:相当于需要被增强的类);

模拟场景:目标类:步兵类,需要上战场打仗(手提精心打造的木棍)

通知类(增强类):高级商店类,只要有士兵来就免费提供(精心打造的暴风大剑)

代理工厂类:需要一个士兵来使用商店的东西(这样才能把士兵与商店联系起来,士兵与商店本来是单独存在的相互不知道)

JDK动态代理实现:

创建maven项目引入spring-aop依赖,使用的是5.1版本

1、目标类需要实现接口,所以先创建一个接口:SoldierInterface(士兵类的接口)

package top.free; /** * 士兵接口 */ public interface SoldierInterface { public void begin(); }

2、创建目标类(步兵类去实现接口),也可以有其他的类(弓箭兵。。。)只要实现了士兵类,都是士兵。

package top.free; /* *步兵类 */ public class Soldier implements SoldierInterface { @Override public void begin() { System.out.println("弓箭士兵开始战斗"); } }

3、通知(也叫增强):商店类

package top.free.advice; public class Store { public void Before(){ System.out.println("为士兵换上暴风大剑。。。"); } public void After(){ System.out.println("士兵胜利归来。。。"); } }

4、创建代理工厂:需要传递过来一个士兵(不管是步兵还是弓箭兵),返回一个被商店加强的士兵

package top.free.proxy; import top.free.SoldierInterface; import top.free.advice.Store; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;
public class MyProxyFactory {   //传递的soldier就是需要被增强的士兵类, public SoldierInterface MyProxyFactory(SoldierInterface soldier){ //通知,此时的商店类,在工厂中new出的实列 Store store = new Store(); SoldierInterface proxysoldier = (SoldierInterface) Proxy.newProxyInstance( MyProxyFactory.class.getClassLoader(),//第一个参数:使用当前类的类加载器 soldier.getClass().getInterfaces(),//第二个参数:传递的soldier士兵对象的接口 new InvocationHandler() {//第三个参数,匿名内部类形式 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //前置调用商店的配置 store.Before(); //调用目标方法,soldier就是传递的士兵对象,args参数默认无参 Object invoke = method.invoke(soldier, args); //后置,士兵执行完方法后调用 store.After(); return invoke; } } ); return proxysoldier; } }

 5、测试运行:

package top.free; import top.free.proxy.MyProxyFactory; public class App { public static void main(String[] args) { //创建工厂 MyProxyFactory myProxyFactory = new MyProxyFactory(); //创建目标类(士兵对象),具体的实现是步兵类 SoldierInterface soldier = new Soldier(); //将创建的士兵传递给工厂,工厂中有商店帮忙打造士兵,用新士兵接收 SoldierInterface newSoldier = myProxyFactory.MyProxyFactory(soldier); //开始  newSoldier.begin(); } }

 

Cglib动态代理实现:

 写Jdk代理时已引入spring相关依赖,此时maven项目中已有spring-core包,Spring5.1版本中,spring-core包中有关于Cglib的类,不需要引入cglib依赖

1、Cglib代理使用的是没有接口的目标类,所以直接创建弓箭兵:

package top.free; /** * Cglib目标类,没有接口,弓箭兵类 */ public class BowsSoldier { public void begin(){ System.out.println("开始射杀敌人。。。"); } }

 

2、通知(商店类):

package top.free.advice; public class Store { public void Before(){ System.out.println("为士兵换上霸王弓。。。"); } public void After(){ System.out.println("士兵胜利归来。。。"); } }

 

3、创建代理工厂:需要一个弓箭兵,返回一个装备好的弓箭兵

package top.free.proxy; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import top.free.BowsSoldier; import top.free.advice.Store; import java.lang.reflect.Method; public class MyCglibProxyFactory { public BowsSoldier MyCglibProxyFactory(BowsSoldier solider){ //创建通知类 Store store = new Store(); //创建Enhance对象 Enhancer enhancer = new Enhancer(); //设置弓箭兵类对象  enhancer.setSuperclass(solider.getClass()); //设置回调方法 enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //放在方法执行前,就是前置增强,装备弓箭  store.Before(); //执行方法,solider就是传递过来的弓箭兵对象 Object invoke = method.invoke(solider); //后置增强  store.After(); return invoke; } }); //创建装备好的士兵 BowsSoldier target1= (BowsSoldier) enhancer.create(); return target1; } }

 4、测试:

package top.free; import top.free.proxy.MyCglibProxyFactory; import top.free.proxy.MyProxyFactory; public class App { public static void main(String[] args) {//创建代理工厂 MyCglibProxyFactory myCglibProxyFactory = new MyCglibProxyFactory(); //创建一个普通的弓箭兵 BowsSoldier soldier = new BowsSoldier(); //传递弓箭兵到工厂,工厂装备好后返回,接收一个装备精良的弓箭兵 BowsSoldier target = myCglibProxyFactory.MyCglibProxyFactory(soldier); //装备精良的弓箭兵开始战斗  target.begin(); } }

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM