Spring学习笔记之——动态代理

Spring中的AOP代理有两种方式:JDK动态代理和CGLIB代理。

JDK动态代理

JDK动态代理通过java.lang.reflect.Proxy类来实现,对于需要实现接口的类,spring默认使用JDK动态代理。其局限性在于必须实现一个或者多个接口。接下来总结一下使用JDK动态代理的步骤:

  1. 创建目标类需要实现的接口类UserDao。
public interface UserDao {
	public void addUser();
	public void deleteUser();
}
  1. 创建目标类UserDaoImpl,实现接口UserDao
public class UserDaoImpl implements UserDao {

	@Override
	public void addUser() {
		System.out.println("添加用户!");

	}

	@Override
	public void deleteUser() {
		System.out.println("删除用户!");

	}

}

  1. 创建切面类MyAspect,定义两个表示切面中的通知的方法。
public class MyAspect {
	public void check_permissions(){
		System.out.println("模拟检查权限……");
	}
	public void log(){
		System.out.println("模拟记录日志……");
	}
}

  1. 创建代理类JDKProxy
    该类实现InvocationHandler接口并编写代理方法。然后调用所有动态代理类的方法。
public class jdkProxy implements InvocationHandler {
	
	//1.声明目标类接口
	private UserDao userDao;
	//2.创建代理方法
	public Object createProxy(UserDao userDao){
		this.userDao=userDao;
		//1.类加载器
		ClassLoader classLoader = jdkProxy.class.getClassLoader();
		//2.被代理对象实现的所有接口
		Class[] clazz = userDao.getClass().getInterfaces();
		//3.使用代理类,进行增强,返回的是代理后的对象.
		//classLoader表示类加载器,clazz表示被代理对象实现的所有接口,this表示代理类jdkProxy本身
		return Proxy.newProxyInstance(classLoader, clazz, this);
	}
	//调用所有动态代理类的方法
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//声明切面
		MyAspect myAspect = new MyAspect();
		//前增强
		myAspect.check_permissions();
		//在目标类上调用方法,并传入参数
		Object obj = method.invoke(userDao, args);
		//后增强
		myAspect.log();
		return obj;
	}

}

5.创建测试类

public class jdkTest {

	public static void main(String[] args) {
		//创建代理对象
		jdkProxy jdkProxy = new jdkProxy();
		//创建目标对象
		UserDao userDao = new UserDaoImpl();
		//从代理对象中获取增强后的目标对象
		//代理对象和被代理对象实现了同一个接口。
		UserDao userDao1 =(UserDao) jdkProxy.createProxy(userDao);
		//执行方法
		userDao1.addUser();
		userDao1.deleteUser();
	}

}

CGLIB代理

要对没有实现接口的类进行代理则可以使用CGLIB代理。CGLIB代理原理是对目标对象进行继承代理,如果目标对象被final修饰则该类无法被CGLIB代理。
在Spring的核心包中已经集成了CGLIB所需要的包,所以开发过程中不需要另外导入jar包。
接下来总结使用cglib代理的步骤:

  1. 创建目标类UserDao。(此处不是接口)
public class UserDao {
	public void addUser() {
		System.out.println("添加用户!");

	}
	public void deleteUser() {
		System.out.println("删除用户!");

	}

}
  1. 创建代理类CglibProxy.该类需要实现MethodInterceptor接口,并实现接口中的intercept()方法。
public class CglibProxy implements MethodInterceptor {
	//代理方法
	public Object createProxy(Object target){
		//创建一个动态类对象.Enhancer()是cglib的核心类。
		Enhancer enhancer = new Enhancer();
		//确定需要增强的类,设置其父类。
		enhancer.setSuperclass(target.getClass());
		//添加回调函数
		enhancer.setCallback(this);
		//返回创建的代理类
		return enhancer.create();
		}

	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		//创建切面类
		MyAspect myAspect =new MyAspect();
		//前增强
		myAspect.check_permissions();
		//目标方法执行
		Object obj = methodProxy.invokeSuper(proxy, args);
		//后增强
		myAspect.log();
		return obj;
	}

}
  1. 创建测试类
public class Test {

	public static void main(String[] args) {
		//创建代理对象
		CglibProxy cglibProxy = new CglibProxy();
		//创建目标对象
		UserDao userDao =new UserDao();
		//获取增强后的目标对象
		UserDao userDao1=(UserDao) cglibProxy.createProxy(userDao);
		//执行方法
		userDao1.addUser();
		userDao1.deleteUser();

	}

}

Spring学习笔记之——动态代理_第1张图片

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