目录
0.前言
1.简介
AOP的目的:
AOP的优势:
2.XML方式实现AOP
3.Spring的各种增强:
4/注释的方式实现AOP
5.Spring的AOP配置,到底使用XML,还是注解:
0.前言
在上一篇文章,我们已经实现了动态的为目标对象做功能增强? 为什么还要学Spring 的AOP呢?
原因是:在为N个service提供代理的时候,我们需要在xml中配置N次.
1.简介
Spring的AOP: 什么叫做AOP:Aspect oritention programming(面向切面编程)
AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来, 便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
降低模块的耦合度、使系统容易扩展、更好的代码复用性.
Spring的AOP使用动态代理实现:
如果一个类实现了接口,那么spring就使用JDK的动态代理完成AOP;
如果一个类没有实现接口,那么spring就是用cglib完成AOP;
AOP当中的概念:
1、切入点(Pointcut):在哪些类,哪些方法上切入(where);
2、增强(Advice): 早期翻译为通知,在方法执行的什么时机(when:方法前/方法后/方法前后)做什么(what:增强的功能);
3、切面(Aspect): 切面=切入点+通知,通俗点就是:在什么时机,什么地点,做什么增强!
4、织入(Weaving): 把切面加入到对象,并创建出代理对象的过程。(该过程由Spring来完成)。
2.XML方式实现AOP
1).Spring AOP开发依赖的jar:
spring-aop-4.1.2.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2).配置aop命名空间:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
</beans>
<!-- 配置AOP:1.切面:What 2.切如位置:Where 3.切入时机:When -->
<aop:config>
<!-- What:做什么增强 -->
<aop:aspect ref="txManager">
<aop:pointcut expression="execution(* com.common.service.*Service.*(..))" id="txPoint"/>
<!-- When:在什么时机做增强(业务方法前/后/前后) -->
<!-- <aop:before method="begin" pointcut-ref="txPoint"/>
<aop:after-returning method="commit" pointcut-ref="txPoint"/>
<aop:after-throwing method="rollback" pointcut-ref="txPoint" throwing="ex"/>
<aop:after method="close" pointcut-ref="txPoint"/> -->
<aop:around method="allWork" pointcut-ref="txPoint"/>
</aop:aspect>
</aop:config>
Notes:
在所有的业务层方法上做增强: execution(* com.pss.service.*Service.*(..))
3.Spring的各种增强:
配置XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置AOP:1.切面:What 2.切如位置:Where 3.切入时机:When -->
<aop:config>
<!-- What:做什么增强 -->
<aop:aspect ref="txManager">
<aop:pointcut expression="execution(* com.common.service.*Service.*(..))" id="txPoint"/>
<!-- When:在什么时机做增强(业务方法前/后/前后) -->
<!-- <aop:before method="begin" pointcut-ref="txPoint"/>
<aop:after-returning method="commit" pointcut-ref="txPoint"/>
<aop:after-throwing method="rollback" pointcut-ref="txPoint" throwing="ex"/>
<aop:after method="close" pointcut-ref="txPoint"/> -->
<aop:around method="allWork" pointcut-ref="txPoint"/>
</aop:aspect>
</aop:config>
<!-- 配置事务管理器 -->
<bean id="txManager" class="com.common.TransactionManager"/>
<!--配置Dao -->
<bean id="employeeDao" class="com.common.dao.impl.EmployeeDaoImpl"/>
<!-- 配置Service -->
<bean id="employeeService" class="com.common.service.impl.EmployServiceImpl">
<property name="dao" ref="employeeDao"/>
</bean>
</beans>
特别注意事务处理文件:@Aspect
package com._07_springaop_anno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
//事务管理器
@Component("txManager")
@Aspect
public class TransactionManager {
@Pointcut("execution(* com._07_springaop_anno.service.*Service.*(..))")
public void txPointcut(){
}
public void begin() {
System.out.println("事务开始");
}
public void commit() {
System.out.println("事务提交");
}
public void rollback() {
System.out.println("事务回滚");
}
public void close() {
System.out.println("释放资源");
}
@Around("txPointcut()")
public Object allWork(ProceedingJoinPoint Pjp) {
begin();
Object ret=null;
try {
ret=Pjp.proceed();
commit();
} catch (Throwable e) {
rollback();
}finally {
close();
}
return ret;
}
}