AOP分类及其实现原理

本文详细介绍了AOP(面向切面编程)的概念,包括连接点、切入点、增强、切面和编织等术语。讨论了AOP的三种织入方式:编译期、类加载期和运行期,并重点分析了AspectJ的类加载期织入。此外,文章还阐述了Spring AOP基于代理的实现,以及如何在运行时动态扩展Java类。最后,探讨了AOP在减少重复代码和提高代码复用性方面的应用,以及动态代理的益处。
摘要由CSDN通过智能技术生成
  • 编译期AOP
    在编译阶段就可生成 AOP代理类,在java编译期采用特殊的编译期,将切面织如java类中。
  • 类加载期AOP
    在类加载期,通过特殊的类加载器,在类字节码加载到JVM时,织入切面。
  • 运行期AOP
    在运行期,采用gclib工具或者jdk动态代理进行切面织入。
    AspectJ采用编译期织入和类加载期织入的方式织入切面,第一种采用特殊编译器,在编译期将采用aspectJ语言编写的切面织入到java类中,第二种方式是采用织入器类包,代理java默认的类加载器,并通过在aop.xml文件中指定切面类和和需要进行切面织入的目标类,最终实现类加载期织入。

aspectj的类加载期织入的实现方式:

AOP中的术语

Join Point(连接点):join point就是一个方法,类中的每一个方法都可以称作为一个连接点。
Pointcut(切入点):满足指定条件的连接点就是切入点,例如在spring配置文件中,通过设置切点表达式指定对相应的方法进行增强。
Advice(增强):在join point上特定的时刻执行的操作。
Aspect(切面):组合了Pointcut与Advice,切点+增强构成切面。
Weaving:将Advice织入join point的这个过程。

Advice的类型:

  • Before advice: 在join point之前执行的advice,但是它不能阻止joint point的执行流程,除非抛出了一个异常(exception)。
  • After returning advice: 在join point这个方法返回之后执行的advice。
  • After throwing advice: 在join point抛出异常之后执行的advice。
  • After(finally) advice: 在join point返回之后或者抛出异常之后执行的advice,通常用来释放所使用的资源。
  • Around advice: 在join point这个方法执行之前与之后执行的advice。

Spring AOP基于代理实现,默认使用jdk动态代理,这也是为什么spring提倡面向接口编程,因为jdk动态代理,需要目标类实现接口,且只能代理接口中的方法,无法代理类中特有方法,要克服这一局限,需要采用cglib来实现动态代理。如果目标类实现了接口,spring使用jdk动态代理,如果没有实现接口,spring使用cglib,spring会自动在CGLIB和JDK动态代理之间切换 。
注:jdk动态代理和cglib都是在运行时动态扩展java类。

AOP有什么作用呢?

当我们需要为多个对象引入一个公共行为,比如日志,操作记录,事务,性能检测等,就需要在每个对象中引用公共行为,这样程序就产生了大量的重复代码,使用AOP可以完美解决这个问题。

动态代理

静态代理的代理类是我们自己定义的,而动态代理的代理类是在运行期自动生成的。如果我们需要在代理类的所有方法中增加公共的操作,如果方法太多的话,我们需要对每个方法都进行修改,重复代码多,而且耦合性高。但是,采用动态代理就可以解决这些问题。举例如下:

public interface Person {
    //定义一个Person接口,里面只有一个方法
    void reportWork();
}

这里以汇报工作为例,每个员工需要汇报工作,但不是直接向老板汇报工作,而是通过一个代理部门主管。

public class Employee implements Person{
	private String name;
	public Employee(String name){
		this.name=name;
	}
	void reportWork(){
		System.out.println(name+"汇报:xxxxxxxxx"+);
	}
}
public class WorkInvocationHandler<T> implements InvocationHandler{
	T target;
	public WorkInvocationHandler(T target){
		this.target=target;
	}
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
	{
        System.out.println("代理执行" +method.getName() + "方法");
        Object result = method.invoke(target, args);
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值