Spring 学习笔记 SpringAOP(1)

AOP技术它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为”Aspect”,即切面。所谓”切面”,简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性.

1.切面(aspect):散落在系统各处的通用的业务逻辑代码,切面用来装载pointcut和advice;

2.通知(advice):指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环 绕通知五类;

3.连接点(joinpoint):被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring 中连接点指的就是被拦截到的方法

4.切入点(pointcut):拦截的方法,连接点拦截后变成切入点

代理方式:

Spring中 AOP中的两种代理: JDK动态代理;CGLIB代理

JDK动态代理:

动态代理机制的实现主要由 java.lang.reflect.Proxy 类和java.lang.reflect.InvocationHandler接口,只能对实现了相应Interface的类使用,如果某个类没有实现任何的Interface,就无法使用动态代理对其产生相应的代理对象! 

在默认情况下,如果Spring AOP发现目标实现了相应的Interface,则采用动态代理为其生成代理对象实例;而如果目标对象没有实现任何的Interface,Spring AOP会尝试使用CGLIB动态字节码生成类库,为目标对象生成代理对象实例!

CGLIB代理:

使用CGLIB扩展对象行为的原理是:对目标对象进行继承扩展,为其生成相应的子类,而子类可以通过覆写来扩展父类的行为;

使用CGLIB类库,实现一个net.sf.cglib.proxy.Callback,或者使用net.sf.cglib.proxy.MethodInterceptor(继承自Callback),通过Enhancer为目标对象动态生成一个子类,将RequestCallback的横切逻辑附加到该子类中

相比于动态代理,CGLIB的优势就是,可以为没有实现任何接口的类进行扩展;

使用 CGLIB 对类进行扩展的唯一限制就是 无法对 final 方法进行覆写

应用:

定义扫描注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RunningLog {

}

定义切面:

@Aspect
@Component
public class RunningAspect implements run {
	@Pointcut("@annotation(com.xxx.xxx.running.service.RunningLog)")
	public void updatePointCut(){};

	@Around(value = "updatePointCut()")
	public Object updateAround(ProceedingJoinPoint jp) throws Throwable{
    ... ....
    }
}

调用时,在方法上加上@RunningLog注解即可。

相关源码

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class targetClass = config.getTargetClass();
			if (targetClass == null) {  throw new AopConfigException(".. ...");}
			if (targetClass.isInterface()) {return new JdkDynamicAopProxy(config);}
			return CglibProxyFactory.createCglibProxy(config);
		}else {
			return new JdkDynamicAopProxy(config);
		}
	}

此代码解释了为什么配置文件中

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> 

proxy-target-class="true" 为true可是dao的代理类还是$Proxy,使用的是JDK动态代理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值