百度整站优化,免费做网站公司ydwzjs,如何欣赏网站,做网站有哪些注意事项Spring AOP AOP 切面编程普通代理类JDK动态代理Cglib动态代理AOPAOP术语AOP切面编程的优势Advice通知类型#xff08;5种#xff09;通知的执行顺序 Order切入点表达式表达式execution注解annotation Spring事务管理Transactional 及 Transactional 的两个属性Transactional … Spring AOP AOP 切面编程普通代理类JDK动态代理Cglib动态代理AOPAOP术语AOP切面编程的优势Advice通知类型5种通知的执行顺序 Order切入点表达式表达式execution注解annotation Spring事务管理Transactional 及 Transactional 的两个属性Transactional 的 rollback 回滚 属性Transactional 的 propagation 传播行为 属性 AOP相关注解总结十一配置切面相关注解通知相关注解事务相关注解 AOP 切面编程
AOP 底层是基于动态代理思想实现的 可以把核心业务业务逻辑看作是一个圆增强的业务逻辑也看成是一个圆核心业务逻辑在增强的业务逻辑的中央这样就形成了一个同心圆切面, 这种编程思想的好处是 无侵入 即 不会对源码进行修改。以一个为核心业务逻辑增加日志的例子来逐步引出动态代理和AOP面向切面编程思想。
普通代理类
最原始的方式是利用代理类的方式为核心业务逻辑增添打印日志的功能这就要求被代理类和增强类要同时实现一个接口来保证方法的一致性但是还需要为每一个代理类都创建一个对象当增强的方法都相同时就造成了代码的重复编写造成了开发效率的降低。下面这种是修改源码的方式。
目前代码存在两个问题 代码耦合性高业务代码和日志代码耦合在了一起 代码复用性低日志代码在每个方法都要书写一遍 JDK动态代理
为了解决基本代理方式的不足产生了JDK动态代理的方式但是这样的方式还有一个不足就是只能对接口的实现类进行代理在此背景下Cglib动态代理又出现了Cglib动态代理可以为类动态创建代理类。 PS: 在创建代理对象时 jdk的速度要高于cglib 所以选择的时候: 当被代理类有接口的时候使用jdk动态代理 当被代理类没有接口的时候使用cglib动态代理
RunWith(SpringJUnit4ClassRunner.class)
ContextConfiguration(classes SpringConfig.class)
public class DeptServiceTest {Autowiredprivate DeptService deptService;Autowiredprivate Logger logger;Testpublic void test1() {InvocationHandler myHandler new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {logger.m1();try {method.invoke(deptService,args);} catch (Exception e) {logger.m3();}logger.m2();return null;}};DeptService deptServiceproxy (DeptService) Proxy.newProxyInstance(deptService.getClass().getClassLoader(),new Class[]{DeptService.class},myHandler);deptServiceproxy.save(null);deptServiceproxy.findAll();deptServiceproxy.findById(null);}} Cglib动态代理 RunWith(SpringJUnit4ClassRunner.class)
ContextConfiguration(classes SpringConfig.class)
public class DeptServiceTest {Autowiredprivate DeptServiceImpl deptService;Autowiredprivate Logger logger;Testpublic void test01() {InvocationHandler invocationHandler new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {logger.m1();try {method.invoke(deptService, args);} catch (Exception e) {logger.m3();}logger.m2();return null;}};DeptServiceImpl deptServiceProxy (DeptServiceImpl) Enhancer.create(DeptServiceImpl.class, invocationHandler);//注意: Enhancer有个硬伤就是无法对已经封装过的targetclass再继续封装多一次无法实现多个interceptor的链式调用。deptServiceProxy.findAll();System.out.println();deptServiceProxy.save(null);System.out.println();deptServiceProxy.findById(null);}
}
首先通过enhancer创建代理类再创建代理类的实例对象
AOP
切面类要使用两个注解 Component 和 Aspect 声明该类为一个切面类并且将该切面类加入到Spring容器中在切面类中可以定义切点 PointCut和通知 5种下面会展开详细叙述
AOP术语 AOP切面编程的优势 Advice通知类型5种
Before前置通知此注解标注的通知方法在目标方法前被执行
AfterReturning 返回后通知此注解标注的通知方法在目标方法后被执行有异常不会执行
AfterThrowing 异常后通知此注解标注的通知方法发生异常后执行
After后置通知此注解标注的通知方法在目标方法后被执行无论是否有异常都会执行Around
Around环绕通知需要自己调用 ProceedingJoinPoint.proceed() 来让原始方法执行其他通知不需要考虑目标方法执行
Around环绕通知方法的返回值必须指定为Object来接收原始方法的返回结果 Object result pjp.proceed();通知的执行顺序 Order
不同切面类中默认按照切面类的全类名字母排序 目标方法前的通知方法字母排名靠前的先执行 目标方法后的通知方法字母排名靠前的后执行 相当于一个嵌套的效果一样类比Filter中的过滤器链的执行顺序也是按照全类名字母靠前的先执行
切入点表达式
切入点表达式描述切入点方法PointCut的一种表达式 作用主要用来决定项目中的哪些方法需要加入通知 常见形式
表达式execution
execution(……)根据方法的签名来匹配常与通配符* 和 …搭配使用 …用在参数表示0或n个参数 *模糊匹配
使用切入点表达式 需要指定 权限修饰符 返回值类型 方法名的全名带全类名 参数 因此excution常与通配符搭配用来定义方法名有规律的切入点
注解annotation
annotation(……) 根据注解匹配使用注解方式需要自定义注解常用来定义方法名无规律的切入点pointcut自定义注解如下所示annotation(注解全类名) 在切点配置自定义注解用于识别对那些方法进行增强 配置切点注解
Spring事务管理
在Spring容器中使用事务时还需要在Spring配置类中配置EnableTransactionMangement注解和Bean配置事务管理器
Transactional 及 Transactional 的两个属性
位置业务service层的方法上、类上、接口上 作用将当前方法交给spring进行事务管理方法执行前开启事务成功执行完毕提交事务出现异常回滚事务
注解用在方法上表示为方法开启事务用在类上表示为类中所有方法开启事务用在接口上表示为接口的所有实现类开启事务
Transactional 的 rollback 回滚 属性
默认情况下只有出现 RuntimeException 才回滚异常rollbackFor属性用于控制让非运行时异常也回滚。 因此需要为 Transactional的rollback属性指定异常类类型让其对所有异常都进行回滚
Transactional 的 propagation 传播行为 属性
事务传播行为指的就是当一个事务方法被另一个事务方法调用时这个事务方法应该如何进行事务控制。通俗点说就是一个有事务注解修饰的方法在被另一个开启了事务的方法调用时该方法的事务怎么办的问题。默认值是required 2中比较常用的是 required 默认 有事务就加入无事务就创建新的 和 requires_new 事务不影响
AOP相关注解总结十一
配置切面相关注解
Component
Aspect
PointCut
annotation
通知相关注解
Before AfterReturning AfterThrowing After Around Oredr
事务相关注解
EnableTransactionMangement
Transactional