纯POJO切面方式实现AOP
基于AOP实现日志输出(POJO实现)
JoinPoint :用于连接目标方法和当前通知方法
public class LogAdvice{
// "自定义"后置通知方法
public void methodAfter(JoinPoint joinpoint){
System.out.println("[日志输出]:--------后置通知----------------");
}
}
基于AOP实现环绕通知(POJO实现)
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;
}
}
数据业务层接口(数据业务层接口方法省略不写了:具体就是实现接口IDemoDAO中的方法)
public interface IDemoDAO {
public void executeInsert();
public void executeBatchInsert();
public void executeBatchUpdate();
}
服务层:在XML中把数据业务层接口注入给服务处,通过服务层调用数据访问层接口中的方法。
public class DemoServiceImpl implements IDemoService{
private IDemoDAO demoDAO;
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 interface IDemoService {
public void doSthBiz();
}
创建AOP配置文件spring-aop.xml
<bean id ="demoDaoBean" class = "com.zhang.dao.DemoDAOImpl"/>
<!-- 业务逻辑层 -->
<bean id = "demoServiceBean" class = "com.zhang.service.DemoServiceImpl">
//注入数据访问层接口
<property name="demoDAO" ref="demoDaoBean"></property>
</bean>
<!-- 通知Advice(POJO) -->
<bean id = "logAdviceBean" class ="com.zhang.advice.LogAdvice"></bean>
<!-- 环绕通知 -->
<bean id = "AdminAdviceBean" class="com.zhang.advice.AdminAdvice"></bean>
<!-- AOP配置 -->
<aop:config>
<!-- 切点:通过表达式,查找目标方法 -->
<aop:pointcut expression="execution(* com.zhang.dao.*.*Insert(..))" id="daoInsertMethod"/>
<!-- 配置切面1:logAdviceBean切点 通知类型 -->
<aop:aspect ref="logAdviceBean">
<!-- 配置通知类型 -->
<!-- 前置通知:在pointcut查找到的目标方法执行前,自动执行前置通知的指定method -->
<aop:before method="methodBefore" pointcut-ref="daoInsertMethod"/>
<aop:after-returning method="methodAfter" pointcut-ref="daoInsertMethod"/>
</aop:aspect>
<!-- 后置通知 -->
<!-- 配置切面二:AdminAdviceBean -->
<!-- 环绕通知 -->
<aop:aspect ref="AdminAdviceBean">
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="daoInsertMethod"/>
</aop:aspect>
</aop:config>
execution表达式解释
execution(* com.zhang.dao….(…))
-
execution():表达式的主体;
-
第一个”*“符号 : 表示返回值的类型任意;
-
com.zhang.dao AOP所切的服务的包名,即,我们的业务部分包名
-
后面的”…“ 表示当前包及子包
-
第二个”*“ 表示类名,*即所有类。此处可以自定义
-
.*(…) 表示任何方法名,括号表示参数,两个点表示任何参数类型
测试类
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.处理结果