spring03-aop
-
spring aop: 只能增强方法,,spring aop 底层是动态代理,,,动态代理的本质是生成一个子类,,重写这个方法,进行增强,,所以final修饰的类和方法,,或者是static静态方法,或者是private修饰的方法,都不能被继承,都会导致spring aop 失效
(图片来源网络,侵删) -
aspectJ aop: 能增强属性,类,静态方法,,等,是一个完整的,独立的,功能十分强大的aop解决方案,,是编译时增强,,性能也高于aop,,当然也支持运行时增强
spring aop 核心概念
- Target : 被拦截下来的对象(要被增强的对象)
- Join Point : 连接点,,, 可以被切面插入的地方
- Pointcut : 切点,, 被切面增强的连接点
- Advice: 通知,切点在连接处执行的代码,增强
- Aspect : 切面 , 通知和切点
- Weaving : 织入,,将切面应用到 Target的过程,,可以在编译的时候weaving,也可以在类加载的时候,,也可以在运行的时候,,织入
- introduction: 引介,,,,为某个类,增加新的方法或者属性,,,
aop的使用
定义一个增强:
public class CalculatorAdvice implements MethodBeforeAdvice { /** * * @param method 当前的方法 * @param args 方法参数 * @param target 当前对象 * @throws Throwable */ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(method.getName()+" 开始执行。。。"); } }xml中配置aop:
这个CalculatorImpl 的类被增强了,,产生了一个新的代理类,,这个容器里面的CalculatorImpl的bean,,被这个新的代理的bean替换掉了,,
public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); // 这里返回的是一个代理对象,,,并不是注入spring中的 ICalculator bean = ctx.getBean(ICalculator.class); // CalculatorImpl calculator = (CalculatorImpl) ctx.getBean("calculator"); // System.out.println("calculator = " + calculator); bean.add(1,2); bean.minus(1,2); }另一种配置xml:
public class LogAdvice { public void before(JoinPoint jp){ // 方法名 String name = jp.getSignature().getName(); System.out.println(name+"开始执行。。"); } public void after(JoinPoint jp){ String name = jp.getSignature().getName(); System.out.println(name+"执行结束。。"); } public void exception(JoinPoint jp,Exception e){ String name = jp.getSignature().getName(); System.out.println(name+"异常。。"+e.getMessage()); } /** * 目标方法的返回值,,必须和这里的参数相匹配,,,该方法才会被触发 * @param jp * @param result */ public void returnAdvice(JoinPoint jp,int result){ String name = jp.getSignature().getName(); System.out.println(name+"返回值。。"+result); } public Object around(ProceedingJoinPoint pjp) throws Throwable { long startTime = System.currentTimeMillis(); Object proceed = pjp.proceed(new Object[]{100,99}); long endTime = System.currentTimeMillis(); System.out.println(pjp.getSignature().getName()+"执行耗时"+(endTime-startTime)); return proceed; } }java代码配置aop:使用自动扫描带@Aspect的切面
/** * * * aspect = pointcut + advice **/ @Aspect public class LogAspect { @Pointcut("execution(* com.cj.CalculatorImpl.*(..))") public void pc1(){} @Before("pc1()") public void before(JoinPoint jp){ // 方法名 String name = jp.getSignature().getName(); System.out.println(name+"开始执行。。"); } @After("pc1()") public void after(JoinPoint jp){ String name = jp.getSignature().getName(); System.out.println(name+"执行结束。。"); } @AfterThrowing(value = "pc1()",throwing = "e") public void exception(JoinPoint jp,Exception e){ String name = jp.getSignature().getName(); System.out.println(name+"异常。。"+e.getMessage()); } /** * 目标方法的返回值,,必须和这里的参数相匹配,,,该方法才会被触发 * @param jp * @param result */ @AfterReturning(value = "pc1()",returning = "result") public void returnAdvice(JoinPoint jp,int result){ String name = jp.getSignature().getName(); System.out.println(name+"返回值。。"+result); } @Around("pc1()") public Object around(ProceedingJoinPoint pjp) throws Throwable { long startTime = System.currentTimeMillis(); Object proceed = pjp.proceed(new Object[]{100,99}); long endTime = System.currentTimeMillis(); System.out.println(pjp.getSignature().getName()+"执行耗时"+(endTime-startTime)); return proceed; } }纯java类写法:
需要在切面上添加注解@EnableAspectJAutoProxy,这个注解是用来识别切面的,相当于在xml中配置
@Aspect @Component // 这个注解是用来识别切面的,,相当于 @EnableAspectJAutoProxy public class LogAspect { ... }@Configuration @ComponentScan public class JavaConfig { }spring aop 动态代理
如果有接口,用的jdk动态代理,,
没有接口,用的cglib动态代理
如果有接口,但是你不想使用jdk动态代理,而是使用cglib,,在@EnableAspectJAutoProxy 设置proxyTargetClass=true 就会使用cglib代理
spring aop拦截
- execution : 零侵入的拦截规则
- 注解
@annotation():方法上面有这个注解
@within() : 类上面有这个注解
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!
