Spring AOP之动态代理

Spring AOP有两种动态代理的方式,一种是jdk的动态代理,一种是cglib实现的动态代理,看下两种代理的实现方式。

1.jdk的动态代理

接口:

public interface ISaler {
	
	public void buy();

}

实现类:

public class CPU implements ISaler{

	@Override
	public void buy() {
		System.out.println("buy cpu");
	}

}

代理类:

public class DynamicsAgent implements InvocationHandler {
	//被代理对象
	private Object obj;

	public DynamicsAgent(Object obj) {
		this.obj = obj;
	}

	//此方法产生一个对象,这个对象可以用来代理被代理的对象,即获取代理对象
	public Object getProxy(){
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		before();
		//执行被代理对象的method方法
		Object o = method.invoke(obj, args);
		after();
		return o;
	}
	
	public void before(){
		System.out.println("-----brfore---------");
	}
	
	public void after(){
		System.out.println("-----after---------");
	}
}

测试类:

public class Test {
	
	public static void main(String[] args) {
		CPU cpu = new CPU();
		DynamicsAgent da = new DynamicsAgent(cpu);
		//生成一个代理对象,用被代理对象的接口表示
		ISaler p = (ISaler)da.getProxy();
		//实际是执行代理类的invoke方法
		p.buy();
	}
	

}

执行结果:

-----brfore---------
buy cpu
-----after---------

2.cglib实现:

实现类同上,可以去掉接口:

public class CPU implements ISaler{

	@Override
	public void buy() {
		System.out.println("buy cpu");
	}

}

代理类:

public class CGLibProxy implements MethodInterceptor {
	
	//被代理对象
	private Object obj;

	public CGLibProxy(Object obj) {
		this.obj = obj;
	}
	
	//此方法产生一个对象,这个对象可以用来代理被代理的对象,即获取代理对象
	public Object getProxy(){
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(obj.getClass());
		enhancer.setCallback(this);
		return enhancer.create();
	}

	@Override
	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy mp) throws Throwable {
		before();
		Object o = mp.invoke(obj, args);
		after();
		return o;
	}
	
	public void before(){
		System.out.println("-----brfore---------");
	}
	
	public void after(){
		System.out.println("-----after---------");
	}

}

测试类:

public class Test {
	
	public static void main(String[] args) {
		CPU c = new CPU();
		CGLibProxy cp = new CGLibProxy(c);
		
		CPU p = (CPU)cp.getProxy();
		//实际是执行代理类的intercept方法
		p.buy();
	}

}

执行结果:

-----brfore---------
buy cpu
-----after---------

两种方式的比较:

采用jdk方式来实现动态代理则需要目标类必须实现接口。

采用cglib方式来实现动态类则目标类不能为final类型。

cglib的执行效率更高,但是需要导入第三方包。

猜你喜欢

转载自blog.csdn.net/w450093854/article/details/83897951
今日推荐