Flask接口签名sign原理与实例代码浅析
270
2022-11-30
springAOP的三种实现方式示例代码
这篇文章给大家介绍了springAOP的实现方式,三种分别是纯XML方式,XML+注解,纯注解方式。
Spring 实现AOP思想使⽤的是动态代理技术
默认情况下, Spring会根据被代理对象是否实现接⼝来选择使⽤JDK还是CGLIB。当被代理对象没有实现
任何接⼝时, Spring会选择CGLIB。当被代理对象实现了接⼝, Spring会选择JDK官⽅的代理技术,不过
我们可以通过配置的⽅式,让Spring强制使⽤CGLIB。
接下来我们开始实现aop,
需求是:横切逻辑代码是打印⽇志,希望把打印⽇志的逻辑织⼊到⽬标⽅法的特定位置(service层transfer⽅法)
纯XML方式
引入aop相关的jar包
TransferServiceImpl.java文件:
package com.lagou.edu.service.impl;
import com.lagou.edu.dao.AccountDao;
import com.lagou.edu.pojo.Account;
import com.lagou.edu.service.TransferService;
import com.lagou.edu.utils.ConnectionUtils;
import com.lagou.edu.utils.TransactionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
/**
* @author 应癫
*/
@Service("transferService")
public class TransferServiceImpl implements TransferService {
// 最佳状态
// @Autowired 按照类型注入 ,如果按照类型无法唯一锁定对象,可以结合@Qualifier指定具体的id
@Autowired
@Qualifier("accountDao")
private AccountDao accountDao;
@Override
public void transfer(String fromCardNo, String toCardNo, int money) throws Exception {
/*try{
// 开启事务(关闭事务的自动提交)
TransactionManager.getInstance().beginTransaction();*/
System.out.println("执行转账业务逻辑");
Account from = accountDao.queryAccountByCardNo(fromCardNo);
Account to = accountDao.queryAccountByCardNo(toCardNo);
from.setMoney(from.getMoney()-money);
to.setMoney(to.getMoney()+money);
accountDao.updateAccountByCardNo(to);
//int c = 1/0;
accountDao.updateAccountByCardNo(from);
}
}
打印日志Util:
package com.lagou.edu.utils;
/**
* @author 应癫
*/
public class LogUtils {
/**
* 业务逻辑开始之前执行
*/
public void beforeMethod(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
System.out.println(arg);
}
System.out.println("业务逻辑开始执行之前执行.......");
}
/**
* 业务逻辑结束时执行(无论异常与否)
*/
public void afterMethod() {
System.out.println("业务逻辑结束时执行,无论异常与否都执行.......");
}
/**
* 异常时时执行
*/
public void exceptionMethod() {
System.out.println("异常时执行.......");
}
/**
* 业务逻辑正常时执行
*/
public void successMethod(Object retVal) {
System.out.println("业务逻辑正常时执行.......");
}
}
public Object arroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕通知中的beforemethod....");
Object result = null;
try{
// 控制原有业务逻辑是否执行
// result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
}catch(Exception e) {
System.out.println("环绕通知中的exceptionmethod....");
}finally {
System.out.println("环绕通知中的after method....");
}
return result;
}
applicationContext.xml
-->
测试:
/**
* 测试xml aop
*/
@Test
public void testXmlAop() throws Exception {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
TransferService transferService = applicationContext.getBean(TransferService.class);
transferService.transfer("6029621011000","6029621011001",100);
}
环绕通知不和前置及后置通知一起使用,因为环绕通知可以实现前置和后置的功能,并且可以控制原有业务逻辑是否执行,非常强大。
XML+注解方式
将上面纯XML方式改为注解方式
将applicationContext.xml中的内容取掉,改为类中添加注解:
package com.lagou.edu.utils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @author 应癫
*/
@Component
@Aspect
public class LogUtils {
@Pointcut("execution(* com.lagou.edu.service.impl.TransferServiceImpl.*(..))")
public void pt1(){
}
/**
* 业务逻辑开始之前执行
*/
@Before("pt1()")
public void beforeMethod(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
System.out.println(arg);
}
System.out.println("业务逻辑开始执行之前执行.......");
}
/**
* 业务逻辑结束时执行(无论异常与否)
*/
@After("pt1()")
public void afterMethod() {udflNnKAUC
System.out.println("业务逻辑结束时执行,无论异常与否都执行.......");
}
/**
* 异常时时执行
*/
@AfterThrowing("pt1()")
public void exceptionMethod() {
System.out.println("异常时执行.......");
}
/**
* 业务逻辑正常时执行
*/
@AfterReturning(value = "pt1()",returning = "retVal")
public void successMethod(Object retVal) {
System.out.println("业务逻辑正常时执行.......");
}
/**
* 环绕通知
*
*/
/*@Around("pt1()")*/
public Object arroundMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕通知中的beforemethod....");
Object result = null;
try{
// 控制原有业务逻辑是否执行
// result = proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
}catch(Exception e) {
System.out.println("环绕通知中的exceptionmethod....");
}finally {
System.out.println("环绕通知中的after method....");
}
return result;
}
}
在application.xml中配置注解驱动:
纯注解模式
我们只需要替换掉xml+注解模式中的注解驱动的部分即可,
将
改为 @EnableAspectJAutoProxy //开启spring对注解AOP的⽀持,在项目中添加到任意个配置类上即可。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~