脚本宝典收集整理的这篇文章主要介绍了Spring AOP,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
AOP(AsPEct Oriented Programing,面向切面编程),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高开发的效率。想比较OOP面向对象编程来说,AOP关注的不再是程序代码中的某个类、某些方法,而是更多考虑的是一种面到面的切入,即层与层之间的一种切入。
通俗化的描述:不通过修改源代码的方式,在主干功能里面添加新功能。
使用登录的例子说明AOP:
AOP能做什么?
应用于日志记录、性能统计、安全控制、事务处理等方面,实现公共功能性的重复使用。
AOP的特点:
降低模块与模块之间的耦合度,提高业务代码的聚合度。(高内聚低耦合)
提高了代码的复用性。
提高系统的扩展性。(高版本兼容低版本)
可以在不影响原有的功能基础上添加新的功能。
AOP的底层实现:
动态代理(JDK+CGLIB)
AOP基本概念:
代理模式在Java开发中是一种比较常见的设计模式。设计目的旨在为服务类与客户类之间插入其他功能,插入的功能对于调用者是透明的,起到伪装控制的作用。如租房的例子︰房客、中介、房东。对应于代理模式中即:客户类、代理类、委托类(被代理类)。
为某一个对象(委托类)提供一个代理(代理类),用来控制对这个对象的访问。
委托类和代理类有一个共同的父类或父接口。
代理类会对请求做预处理、过滤,将请求分配给指定对象。
生活中常见的代理模式:
房东委托中介出租房子、新人委托婚庆公司举办婚礼。
代理模式的两个设计原则:
1. 委托类和代理类有共同的行为
2. 代理类能够增强委托类的行为
常见的代理模式:
1. 静态代理
2. 动态代理
实现高内聚、低耦合
某个对象提供一个代理,代理角色固定,以控制对这个对象的访问。代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。
有共同行为(租房) —— 接口
目标角色(房东) —— 实现行为
代理角色(中介) —— 实现行为(增强目标对象行为)
下面举Java代码示例:
接口类:租房子
public interface RentHouse { // 定义接口——行为
void toRentHouse();
}
目标类(需要增强方法的类):房东类,房东有租房子的需求
public class Owner implements RentHouse{
/**
* 静态对象 ——> 目标角色
* 1. 实现行为
*/
@override
public void toRentHouse() {
System.out.println("两室一厅,月租五千!");
}
}
代理类:中介类,中介实现租房子的需求,并增强方法
public class AgentProxy implements RentHouse{
/**
* 静态对象 ——> 代理角色
* 1. 实现行为
* 2. 增强目标角色行为
*/
// 目标对象
private RentHouse target; // 使用的接口引用,利用接口的动态绑定机制,根据当前实现接口的对象调用所属方法
// 通过带参构造器获取目标对象
public AgentProxy(RentHouse target) {
this.target = target;
}
// 实现行为
@Override
public void toRentHouse() {
// 用户增强行为
System.out.println("房型朝南,采光好!");
// 代理对象调用目标对象的方法
target.toRentHouse(); // 自动向下转型,调用实现子类的方法,动态绑定机制
// 用户增强行为
System.out.println("价格可议!");
}
}
测试:
public class test {
public static void main(String[] args) {
// 目标对象
Owner owner = new Owner(); // 注意!这里是目标对象
// 代理对象
AgentProxy agentProxy = new AgentProxy(owner);
// 通过代理对象调用目标对象中的方法
agentProxy.toRentHouse();
}
}
/**
* 房型朝南,采光好!
* 两室一厅,月租五千!
* 价格可议!
*/
需要注意!在代理类中,使用接口的引用,作为构造器传参进来的目标对象的引用,而在使用中,要用目标对象实例传进来,使用接口调用的动态绑定机制,根据当前接口实现类调用所属的方法。
相比于静态代理,动态代理在创建代理对象上更加的灵活,动态代理类的字节码在程序运行时,由Java反射机制动态产生。它会根据需要,通过反射机制在程序运行期,动态的为目标对象创建代理对象,无需程序员手动编写它的源代码。动态代理不仅简化了编程工作,而且提高了软件系统的可扩展性,因为反射机制可以生成任意类型的动态代理类。代理的行为可以代理多个方法,即满足生产需要的同时又达到代码通用的目的。
动态代理的两种实现方式:
1. JDK动态代理(JDK动态代理的目标对象必须有接口实现)
2. CGLIB动态代理(没有接口情况)
Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个接口或多个接口动态地生成实现类,此类提供了如下操作方法:
/**
* 返回一个指定接口的代理类的实例方法调用分派到指定的调用处理程序。(返回代理对象)
* loader:一个classLoader对象,定义了由哪个classLoader对象来对生成的代理对象进行加载
* interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果
* 我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
* h:一个InvocationHandler接口,表示代理实例的调用处理程序实现的接口。每个代理实例都具有一个
* 关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的invoke方法(传入工nvocationHandler接口的子类)
*/
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
每一个代理类都需要实现InvocationHandler接口。
补充:对invoke方法
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能使用JDK的动态代理,cglib是针对类来实现代理的,它的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
实现原理:继承思想
测试:
以上是脚本宝典为你收集整理的Spring AOP全部内容,希望文章能够帮你解决Spring AOP所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。