spring aop原理(动态代理)

来源:互联网 发布:磁铁车牌号码贴 淘宝 编辑:程序博客网 时间:2024/06/03 21:58
spring aop 的主要原理就是动态代理。
代理模式(proxy):动态代理(JDk/cglib)和静态代理

JDk与CGLib动态代理区别:如果目标对象是接口,那么适合使用JDK来生成代理,负责spring会使用CGLIB来生成代理。

JDk动态代理:
动态代理必须实现InvocationHandler接口,实现invoke()方法;

invoke()方法有3个参数:分别代表代理的真实对象、调用的对象的方法的Method对象、方法的参数

例子:
IPerson.java:

public interface IPerson {void test(String test);}
Person.java:

public class Person implements IPerson{@Overridepublic void test(String test) {System.out.println("test......"+test);}}
PersonProxy.java 实现InvocationHandler接口:

public class PersonProxy  implements InvocationHandler {//目标对象private IPerson person;public PersonProxy(IPerson person){this.person = person;}public IPerson getProxy(){Class<?>[] interfaces = new Class[]{IPerson.class};//newProxyInstance在jvm运行时动态生成的对象//参数分别是:类加载对象、interface数组、InvocationHandler对象return (IPerson) Proxy.newProxyInstance(IPerson.class.getClassLoader(),interfaces,this);}@Overridepublic Object invoke(Object target, Method method, Object[] params)throws Throwable {//Person.test()执行前添加自己的操作System.out.println("start...... ");Object obj = method.invoke(person, params);//Person.test()执行后添加自己的操作System.out.println("end......");return obj;}}
测试类:

public class Test {public static void main(String[] args) {IPerson person = new Person();PersonProxy personProxy = new PersonProxy(person);IPerson per = personProxy.getProxy();//当用代理对象调用方法时,实际上调用与代理对象关联的InvocationHandler的invoke(),并不是自己真实调用per.test("测试数据");}}
执行结果:
start...... 
test......测试数据
end......

接下来看一个简单aop的配置文件:

<bean id="person" class="com.aop.Person"/><bean id="things" class="com.aop.Things"/><aop:config><aop:aspect id="thing" ref="things"><aop:pointcut id="addMethod" expression="execution(* com.aop.IPersonDao.*(..))"/><aop:before method="wear" pointcut-ref="addMethod"/><aop:after method="working" pointcut-ref="addMethod"/></aop:aspect></aop:config></bean>
配置文件意思:在执行IPersonDao的所有方法前执行things.wear()方法,在执行IPersonDao的所有方法后执行things.working()方法
因此,我们就可以把上面代码的
System.out.println("start...... ") 替换成things.wear()(利用IOC的反射原理),
System.out.println("end......")替换成things.working()(利用IOC的反射原理).



0 0
原创粉丝点击