AspectJ注解驱动实现AOP
使用AspectJ 需要导入Spring AOP和 AspectJ相关jar包
-
spring-aop-4.2.4.RELEASE.jar
-
com.springsource.org.aopalliance-1.0.0.jar
-
spring-aspects-4.2.4.RELEASE.jar
-
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
目标类,定义切面类 -
@ MethodBeforeAvice:前置输出
- @AfterReturnAdvice:后置通知(通过returning属性 可以定义方法返回值,作为参数)
- @ThrowsAdvice:异常通知(通过设置throwing属性,可以设置发生异常对象参数)
- @After 最终通知
- @Around 环绕通知(around方法的返回值就是目标代理方法执行返回值,参数为ProceedingJoinPoint 可以调用拦截目标方法执行)
@Aspect//切面
@Component//spring容器中的组件
public class LogAdvice{
//用于连接目标方法和当前通知方法
// "自定义"后置通知方法
//要增强的代码
@After("com.zhang.pointcut.MyPointcut.doInsertMethodPointcut()")
public void methodAfter(JoinPoint joinpoint){
System.out.println("[日志输出]:--------后置通知----------------");
}
}
定义环绕通知
public class AdminAdvice {
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("【日志输出】:-------环绕通知--------");
System.out.println("&&&&&&&&&&&&&&&&");
Object returnVal = joinPoint.proceed();
System.out.println("&&&&&&&&&&&&&&&&&");
System.out.println("【日志输出】:-------环绕通知结束--------");
return returnVal;
}
}
定义MyPointcut类
• 在每个通知内定义切点,会造成工作量大,不易维护,对于重复的切点,可以使用@Pointcut进行定义
• 切点方法:private void 无参数方法,方法名为切点名
• 当通知多个切点时,可以使用|| 进行连接
public class MyPointcut {
@Pointcut("execution(* com.zhang.dao.*.*Insert(..))")
public void doInsertMethodPointcut() {
}
}
定义主配置类
@Configuration
@ComponentScan
@EnableAspectJAutoProxy//注册AutoProxyCreator(自动代理工厂)
public class AppConfig {
}
配置数据访问层
@Repository
public class DemoDAOImpl implements IDemoDAO{
@Override
public void executeInsert() {
System.out.println("[数据访问操作]:1.连接数据库");
System.out.println("[数据访问操作]:2.执行SQL------------------Insert");
System.out.println("[数据访问操作]:3.处理结果");
}
@Override
public void executeBatchInsert() {
System.out.println("[数据访问操作]:1.连接数据库");
System.out.println("[数据访问操作]:2.执行SQL---------------bathcInsert");
System.out.println("[数据访问操作]:3.处理结果");
}
@Override
public void executeBatchUpdate() {
System.out.println("[数据访问操作]:1.连接数据库");
System.out.println("[数据访问操作]:2.执行SQL---------------Update");
System.out.println("[数据访问操作]:3.处理结果");
}
}
配置业务层
@Service
public class DemoServiceImpl implements IDemoService{
@Autowired
private IDemoDAO demoDAO;
@Override
public void doSthBiz() {
System.out.println("[业务逻辑层]:执行业务逻辑1");
System.out.println("[业务逻辑层]:执行业务逻辑2");
System.out.println("[业务逻辑层]:执行业务逻辑3");
demoDAO.executeInsert();
demoDAO.executeBatchInsert();
demoDAO.executeBatchUpdate();
}
public IDemoDAO getDemoDAO() {
return demoDAO;
}
public void setDemoDAO(IDemoDAO demoDAO) {
this.demoDAO = demoDAO;
}
}
测试类
public class Test02 {
public static void main(String[] args) {
ApplicationContext Context =new AnnotationConfigApplicationContext(AppConfig.class);
IDemoService demoService= Context.getBean(IDemoService.class);
demoService.doSthBiz();
}
}
测试类
[业务逻辑层]:执行业务逻辑1
[业务逻辑层]:执行业务逻辑2
[业务逻辑层]:执行业务逻辑3
[数据访问操作]:1.连接数据库
[数据访问操作]:2.执行SQL------------------Insert
[数据访问操作]:3.处理结果
[日志输出]:--------后置通知----------------
[数据访问操作]:1.连接数据库
[数据访问操作]:2.执行SQL---------------bathcInsert
[数据访问操作]:3.处理结果
[日志输出]:--------后置通知----------------
[数据访问操作]:1.连接数据库
[数据访问操作]:2.执行SQL---------------Update
[数据访问操作]:3.处理结果