SpringAOP知识点

SpringAOP的一点理解
其实springaop就是一个拦截器,springaop通过代理模式实现方法的拦截。
SpringAOP的基本术语
1、切面(@Aspect):拦截器类,其中会定义切点以及通知
2、通知:切面当中的方法,包括:
前置通知(@Before):在动态代理反射原先方法前调用的方法
后置通知(@After):在动态代理反射完原有方法后调用的方法
返回通知(@AfterReturning):如果方法正常执行,在调用完后置通知后,就调用返回通知
异常通知(@AfterThrowing):如果方法出现异常,在调用完后置通知后,就调用异常通知
环绕通知:可以决定是否调用目标方法,同时可以控制方法的返回对象(这个通知具有一些细节,接下来会进一步说明)
3、引入:往代理对象中添加新的方法,但是新的方法不会被拦截
4、切点(@Pointcut):即定义需要拦截的方法的特征,可以通过正则表达式匹配,也可以通过类的全限定名
5、连接点:需要拦截的方法
6、织入:生成代理对象并将切面内容嵌入流程中,将切面内容嵌入到流程中是什么意思呢?例如现在定义了前置通知,那么代理对象在调用被代理对象的方法之前就会调用前置通知。

下面举一个简单的例子,项目结构:
Roleinterface:

package com.springdemo3;
public interface Roleinterface {
     void print();
}

Roleimplement:

package com.springdemo3;
public class Roleimplement implements Roleinterface{
    //连接点
	public void print() {
		System.out.println("this is AOP");
	}
}

AOP(切面):

package com.springdemo3;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
 
@Aspect
public class AOP {
    //切点
	@Pointcut("target(com.springdemo3.Roleimplement)")
	public void print() {};
    //前置通知
	@Before("print()")
	public void beforeprint() {
		System.out.println("这是前置方法");
	}
    //后置通知
	@After("print()")
	public void afterprint() {
		System.out.println("这是后置方法");
	}
    //返回通知
	@AfterReturning("print()")
	public void afterreturning() {
		System.out.println("正常返回");
	}
    //异常通知	
	@AfterThrowing("print()")
	public void afterthrowing() {
		System.out.println("异常防护");
	}
}

configurations(配置类):

package com.springdemo3;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Bean;
 
@Configuration
@EnableAspectJAutoProxy
public class configurations {
	@Bean
	public Roleimplement getRoleinplement() {
		return new Roleimplement();
	}
	@Bean
	public AOP getAOP() {
		return new AOP();
	}
}

App(启动类):

import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext ctx = new AnnotationConfigApplicationContext(configurations.class);
    	Roleinterface temp=(Roleinterface)ctx.getBean(Roleinterface.class);
    	temp.print();
    }
}

运行结果:
这是前置方法
this is AOP
这是后置方法
正常返回

关于springAOP相应的内容都已经标记出,接下来我们看看环绕通知,在切面中添加函数,函数参数ProceedingJoinPoint可以调用proceed方法,该方法会调用连接点,同时调用前置通知:

@Around(value = "print()")
public void aroundfunc(ProceedingJoinPoint func) {
	System.out.println("执行环绕方法");
	try {
		func.proceed();
	} catch (Throwable e) {
		e.printStackTrace();
	}
	System.out.println("环绕方法执行完毕");
}

运行结果:
执行环绕方法
这是前置方法
this is AOP
环绕方法执行完毕
这是后置方法
正常返回

当切面中存在环绕通知时,在外部调用连接点方法,其实调用的是环绕通知,proceed方法允许环绕通知调用连接点方法,proceed方法将前置通知与连接点捆绑在一起,环绕通知就相当于连接点,根据环绕通知的执行结果,决定调用异常通知或是正常通知

springAOP的引入
我对springAOP引入的理解就是增强代理对象的功能,其实就是让代理对象继承某些接口(不能是类),内部是通过反射的方式调用接口实现类的方法,为什么只能引入接口的方法呢?这是java代理方式决定的,CGLIB代理已经继承被代理类了(java是单继承),JDK代理对象生成的时候只能传递接口
(JDK生成代理对象的方法为Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), this),看不到与类继承有关的参数)

Userinterface:

package com.springdemo3;
public interface Userinterface {
     void print_sec();
}

Userimplement:

package com.springdemo3;
public class Userimplement implements Userinterface{
	public void print_sec() {
		System.out.println("这是引入");
	}
}

在AOP(切面)中添加:

//value表示引入应用于哪些被代理的代理对象
//defaultImpl表示接口的默认实现类是谁,引入的实现类会被注册为通知(advice)
@DeclareParents(value="com.springdemo3.Roleinterface+",defaultImpl=Userimplement.class)
Userinterface userinterface;

当有多个通知应用于同一个连接点时,通知的执行顺序是不确定的,可以在切面类中使用@Order(优先级)来指定执行顺序,此时spring会将多个通知组织成责任链的模式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值