网站开发注意,百度知道问答,动画设计专业就业前景和就业方向,做的新网站网上搜不到一、AOP 1 Spring AOP 的实现原理 是对OOP编程方式的一种补充。翻译过来为“面向切面编程”。 1 AspectJ是静态代理的增强#xff1a;所谓静态代理就是AOP框架会在便一阶段生成AOP代理类#xff0c;也叫编译器增强。 2 使用Spring AOP 与AspectJ 的静态代理不同#xff0c…一、AOP 1 Spring AOP 的实现原理 是对OOP编程方式的一种补充。翻译过来为“面向切面编程”。 1 AspectJ是静态代理的增强所谓静态代理就是AOP框架会在便一阶段生成AOP代理类也叫编译器增强。 2 使用Spring AOP 与AspectJ 的静态代理不同Spring AOP使用的是动态代理动态代理指AOP框架不会去修改字节码而是在内存中临时生成一个AOP对象这个AOP对象包含了目标对象的全部方法并在特定的切点做了增强处理并回调原对象的方法。Spring AOP中的动态代理有两种JDK动态代理代理必须实现一个接口、CGLIB动态代理代理可以不实现接口几个概念 切面Advisor是AOP中的一个术语表示从业务逻辑中分离出来的横切逻辑比如性能监控、日志处理、权限控制等。 这些功能都可以从核心的业务逻辑中抽离出去。可以解决代码耦合的问题职责更加单一。封装了增强和切点。增强Advice增强代码的功能的类横切到代码中。目标目标方法JDK代理或目标类CGLIB代理。代理通过ProxyFactory类生成分为JDK代理、CGLIB代理。切点通过一个条件来匹配拦截的类这个条件成为切点。连接点作为增强方法的入参可以获取目标方法的信息。 增强 织入Weaving将切面应用到目标对象并导致代理对象创建的过程。 1 前置增强Before在目标方法前调用。2 后置增强AfterAdvice在目标方法后调用。3 环绕增强AroundAdvice将Before和After甚至抛出增强和返回增强合到一起。4 返回增强AfterReturningAdvice在方法返回结果后执行该增强可以接收到目标方法返回的结果。5 抛出增强AfterThrowingAdvice在目标方法抛出对应的类型后执行可以接收到对应的异常信息。 引入增强DeclareParentsAdvice想让程序在运行的时候动态实现某个接口需要引入增强。 3 注解Spring AspectJ 1 对切面类添加 Aspect 注解将切面类和目标类放入到IOC容器中可以通过context:component-scan base-package/进行扫描。2 添加增强方法包括增强类型和切点表达式以及连接点。3 在Spring 配置文件中添加aop:aspectj-autoproxy proxy-target-classtrue/ false表示只能代理接口JDK动态代理true表示代理类CGLIB代理。 3.1 通过切点表达式AspectJ execution进行拦截 步骤一配置pox.xml:
!--Spring AOP依赖--
dependencygroupIdorg.springframework/groupIdartifactIdspring-aop/artifactIdversion${spring.version}/version
/dependency
dependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion${spring.version}/version
/dependency步骤二spring-config.xml
!-- 注解扫描--
context:component-scan base-packagecom.sean.aoptest/context:component-scan
!-- 设置aop动态代理类型true为代理类false为代理接口 --
aop:aspectj-autoproxy proxy-target-classtrue/步骤三编写代码在这里我上传一段测试代码
RunWith(SpringJUnit4ClassRunner.class)
ContextConfiguration(locations{classpath:spring-config-test.xml})
public class SpringTest{Autowiredprivate Student student;Testpublic void test01(){System.out.println(student.say(zengxing));}
}Component
class Student implements Person{Overridepublic String say(String name) {// TODO Auto-generated method stub
// if (name.equals(zengxing)) {
// throw new RuntimeException(名字不能是 name); //要抛出运行时异常
// }return Hello, name;}}///*
around before...
before
around after...
after
str:Hello, zengxing
afterReturningAdvice
Hello, zengxing
*///Aspect
Component
class LoggingAspect{//前置Before(execution(String say(String)))public void before(JoinPoint point){System.out.println(before);}//后置After(execution(String say(String)))public void after(JoinPoint point){System.out.println(after);}//环绕Around(execution(String say(String)))public Object around(ProceedingJoinPoint point) throws Throwable{System.out.println(around before...);Object result point.proceed();System.out.println(around after...);return result;}//返回AfterReturning(valueexecution(String say(String)), returningstr)public void afterReturningAdvice(JoinPoint point, String str){System.out.println(str: str);System.out.println(afterReturningAdvice);}//抛出AfterThrowing(value execution(String say(String)), throwing e)public void afterThrowingAdvice(JoinPoint point, Exception e){String message e.getMessage();System.out.println(message);System.out.println(AfterThrowingAdvice...);}
}3.2 通过切点注解表达式AspectJ annotation进行拦截 开发步骤 1 定义注解类
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
interface AuthorityTag { }2 为切面类中增强指定注解表达式
Aspect
Component
class AuthorityAspect{Before(annotation(com.sean.aoptest.AuthorityTag))public void before(JoinPoint point){System.out.println(authority before);}
}3 在目标类目标方法上标注注解
Component //将对象放入到IOC容器中
class Car1 implements Wheel{AuthorityTag //标注切入的的增强Overridepublic void run(){System.out.println(I am a car, i can run);}
}4 小的知识点 利用方法签名编写 AspectJ 切点表达式 execution * com.sean.Calculator.* (…)匹配Calculator中声明的所有方法 第一个 * 代表任意修饰符及任意返回值。第二个 * 代表任意方法。…匹配任意数量的参数。若目标类与接口与该切面在同一个包中可以省略包名。execution public * Calculator.*(…)匹配ArithmeticCalculator 接口的所有公有方法。execution public double Calculator.*(…)匹配Calculator中返回double类型数值的方法。execution public double Calculator.*(double, …)匹配第一个参数为double类型的方法…匹配任意数量任意类型的参数。execution public double Calculator.*(double, double)匹配参数类型为doubledouble类型的方法。 可以结合切点表达式使用 , ||, ! 来合并。如 execution(void run()) || execution(void say()) 切面优先级 可以通过实现Ordered接口或利用Order注解指定。1 实现Ordered接口getOrder()方法返回的值越小优先级越高。2 使用Order注解需要出现在注解中同样是值越小优先级越高。
参考博客https://blog.csdn.net/qq_16605855/article/details/73465865