spring aop原理(动态代理)

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{
	@Override
	public 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);
	}

	@Override
	public 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的配置文件:


	
	
	
		
			
			
			
				
		
配置文件意思:在执行IPersonDao的所有方法前执行things.wear()方法,在执行IPersonDao的所有方法后执行things.working()方法
因此,我们就可以把上面代码的
System.out.println("start...... ") 替换成things.wear()(利用IOC的反射原理),
System.out.println("end......")替换成things.working()(利用IOC的反射原理).



你可能感兴趣的:(aop,java,spring)