spring 的AOP和动态代理分析

spring的AOP到底是什么呢?
看看百度怎么说

AOP(Aspect Oriented Programming 面向切面编程),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。常用于日志记录,性能统计,安全控制,事务处理,异常处理等等

用自己的话来说,就是将一些与业务核心逻辑无关并且多个对象公用的代码块封装起来,然后供切入到代码中, 供它们使用


下面看看代码

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)

上面这个就是动态代理类(Proxy)类中的创建代理对象的方法,下面介绍一下方法的三个参数:

  • ClassLoader loader:方法需要动态生成一个类,这个类实现了A和B两个接口,然后创建这个类的对象。需要生成一个类,而且这个类也需要加载到方法区中,所以我们需要一个ClassLoader来加载该类
  • Class<?>[] interfaces:我们需要代理对象的.Class对象的数组
  • InvocationHandler h:调用处理器

InvocationHandler
这就是我们代理了这个接口之后,要进行的所有操作都在这里面,这个类里,我们可以重写一个叫做invoke的方法,并且可以将要代理的实体对象传入,在invoke里可以进行逻辑方法添加还能调用传入的实例对象的方法,这一步就相当于完成一个增强

package cn.et.utils;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class MyInvocationHandler implements InvocationHandler{
	private Object targetObj;
	public MyInvocationHandler(Object targetObj){
		this.targetObj = targetObj;
	}
 
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("权限验证");
		Object resultObj = method.invoke(targetObj, args);
		System.out.println("日志记录");
		return resultObj;
	}
}


总结:使用动态代理的方法实现aop的步骤是,我们必须有一个接口,我们可以新建一个创造代理的类的类newProxyInstance,这个类中接受要被代理对象实现的接口,并且接受类加载器和一个执行器 InvocationHandler,通过这个执行器我们能接受那个实现接口的对象,在这个类里可以重写一个invoke方法,这个方法里既能调用被代理对象的方法,还能使用 自己添加的类的方法,最后返回值就是代理对象的返回值

package cn.et.utils;
 
 
 
import java.lang.reflect.Proxy;
 
import org.junit.Test;
 
import cn.et.dao.UserDao;
import cn.et.dao.impl.StudentDao;
import cn.et.dao.impl.UserDaoImpl;
 
public class Checkout {
	@Test
	public void Testing(){
		UserDao userDao = new UserDaoImpl();
		/*
		Spring AOP(面向切面编程),扩展功能不修改源代码实现,采用横向抽取机制,取代了传统纵向继承体系重复性代码
		横向抽取机制,底层使用动态代理方式实现
			针对有接口的情况时使用JDK中的java.lang.reflect类库提供的动态代理
			针对没有接口的情况时,使用Cglib框架提供的动态代理
		*/
		MyInvocationHandler handler = new MyInvocationHandler(userDao);
		UserDao proxyUserDao = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(),handler);
		proxyUserDao.addUser();
		
		System.out.println("。。。。。。。。。。。。。");
		
		CglibProxy proxy = new CglibProxy();  
	    StudentDao proxyImp = (StudentDao)proxy.getProxy(StudentDao.class);  
	    proxyImp.addStudent();  
		
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43146461/article/details/82929118