JDK动态代理和Cglib动态代理

Spring AOP使用了两种代理机制:一种是基于JDK的动态代理;另一种是基于CGLib的动态代理

JDK动态代理只能提供对接口的代理,不能实现对类的代理

所以Spring AOP也采用了Cglib动态代理技术

下面采用实例分别叙述JDK动态代理和CGLib的区别

JDK动态代理:

1、

业务接口和实现类:

public interface BusinessService {
	void ink_print();
}	

public class BusinessServiceImpl implements BusinessService {
	@Override
	public void ink_print() {
		System.out.println("---------------业务主体----------------");	
	}
}

JDK动态代理涉及到两个类Proxy和InvocationHandler

Proxy:生成业务实体对象,产生代理类

InvocationHandler:用来将横切代码和业务代码结合起来

2、

实现InvocationHanlder接口:

public class JdkHandler implements InvocationHandler {
	private Object target;
	
	public JdkHandler(Object target){
		this.target = target;
	}
	
	/**
	 * 将横切逻辑和业务方法结合在一起
	 * ①System.out.println("---------------拦截AOP----------------");
	 * ②System.out.println("---------------业务主体----------------");
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//拦截从此展开
		System.out.println("---------------拦截AOP----------------");
		//业务主体代码,method.invoke是通过反射机制调用业务对象的方法
		Object obj = method.invoke(target, args);
		return obj;
	}

}

 3、创建代理实例

public class TestJdkProxy {
	
	public static void main(String[] args) {
		BusinessService target = new BusinessServiceImpl();
		JdkHandler handler = new JdkHandler(target);
		//根据target、handler产生代理实例
		BusinessService proxy = (BusinessService) Proxy.newProxyInstance(
				target.getClass().getClassLoader(),
				target.getClass().getInterfaces(),
				handler);
		proxy.ink_print();
		
	}
}

 调用主业务的方法体,然后通过Proxy产生代理类,最终由代理类去执行操作,这就是代理操作。

 

CGlib动态代理

CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用

实现MethodInterceptor:创建动态代理类,将业务方法代码和横切逻辑代码组合

public class CglibProxy implements MethodInterceptor {
	
	private Enhancer enhancer = new Enhancer();
	
	public Object getProxy(Class clazz){
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		return enhancer.create();
	}
	
	@Override
	public Object intercept(Object obj, Method arg1, Object[] arg2,
			MethodProxy proxy) throws Throwable {
		System.out.println("---------------拦截AOP----------------");
		Object target = proxy.invokeSuper(obj, arg2);
		return target;
	}

}

 测试类: 此时就是和JDK动态代理不同,创建类代理,而不是接口

public class TestCglibProxy {

	public static void main(String[] args) {
		CglibProxy proxy = new CglibProxy();
		BusinessServiceImpl businessService = (BusinessServiceImpl) proxy.getProxy(BusinessServiceImpl.class);
		businessService.ink_print();
	}

}

 

 

 

 

你可能感兴趣的:(JDK动态代理)