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

<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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值