Aop手动代理(jdk动态代理和CGLIB代理的区别)

Aop手动代理分为jdk动态代理和CGLIB代理

1、jdk动态代理是通过jdk中的java.lang.reflect.Proxy类来实行的,底层的原理是根据接口和增强的方法,创建一个新类,所以必须基于接口

2、CGLIB(code generation libray)是一个高性能开元的代码生成包,它的底层是通过ASM(一个小而快的字节码处理框架)来转换字节码,为一个类创建一个子类,然后对子类进行增强,解决jdk的无接口代理问题

区别:jak动态代理必须有一个接口,CGLIB可以直接代理一个类

代码演示

定义一个Teacher类,里面有一个start()方法

public void start() {
		System.out.println("开始上课");
	}

定义一个切面类

public class AspectJdk {
	public void before() {
		System.out.println("方法执行前");
	}

	public void after() {
		System.out.println("方法执行后");
	}
}

通过jdk动态代理

private static UserDao getUser(UserImpl userImpl, AspectJdk aspectJdk) {

		return (UserDao) Proxy.newProxyInstance(userImpl.getClass().getClassLoader(), // 代理类的类加载器
				new Class[] { UserDao.class }, // 有哪些接口,这个类必须有接口
				new InvocationHandler() { // 方法增强

					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// proxy不能用,因为proxy代表的是代理类,用的话会导致内存溢出
						// method代表的是增强的方法
						// args代表的是参数
						aspectJdk.before();
						Object object = method.invoke(userImpl, args);
						aspectJdk.after();
						return object;
					}
				});
	}

 通过CGLIB代理

	public static Teacher getTeacher(Teacher teacher, AspectJdk aspectJdk) {
        //参数:teacher:代表的是被代理的类 aspectJdk:代表的是切面
		// Enhancer类 允许为非接口类型创建一个Java代理。
		// Enhancer动态创建了给定类型的子类但是拦截了所有的方法。和Proxy不一样的是,不管是接口还是
          类他都能正常工作。
		Enhancer enhancer = new Enhancer();
		// 设置代理类要要为谁代理
		enhancer.setSuperclass(Teacher.class);
		// 设置代理类的回掉函数
		enhancer.setCallback(new MethodInterceptor() {

			public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy)
					throws Throwable {
				aspectJdk.before();
				Object obj = method.invoke(teacher, args);
				aspectJdk.after();
				return obj;
			}
		});

		return (Teacher) enhancer.create();

	}

猜你喜欢

转载自blog.csdn.net/weixin_42373448/article/details/81269384