Spring的AOP
- 可以用于事务管理、日志管理、性能监测等
- Spring实现Aop有两种方案:JDK(若目标对象实现了若干接口)与CGLIB(若目标对象没有实现任何接口)
(一)Xml版实现AOP
准备接口:IUserService
public interface IUserService {
void save();
void delete();
}
准备实现 UserServiceImpl
public class UserServiceImpl implements IUserService {
@Override
public void save() {
System.out.println("UserServiceImpl:save");
}
@Override
public void delete() {
System.out.println("UserServiceImpl:delete");
int i = 1 / 0;
}
}
事务管理器对象(模拟的)
public class TxManager {
public void begin(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交事务");
}
public void rollback(Throwable throwable){
System.out.println("回滚事务 原因 : " + throwable.getMessage());
}
public void close(){
System.out.println("关闭事务");
}
}
1.添加aop命名空间
<beans xmlns="http://www.springframework.org/schema/beans"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
2.准备两个bean
<!--创建一个业务对象-->
<bean id="userService" class="com.lty._01aopxml.service.impl.UserServiceImpl"></bean>
<!--创建一个事务对象-->
<bean id="txManager" class="com.lty._01aopxml.TxManager"></bean>
3.xml配置
<aop:config>
<!--
aop:pointcut 配置切点
id 切点名称(可以随便取)
expression 表达式execution(),定位到接口它的实现也全部找到
*:任意返回值
com.lty._01aopxml.service:定位的包名
I*Service:以I开始以Service结尾的所有接口类
*:任意方法
(..):任意参数
-->
<aop:pointcut id="pointcut" expression="execution(* com.lty._01aopxml.service.I*Service.*(..))"></aop:pointcut>
<!--
aop:aspect 切面(由切点与增强【通知】组成)
ref="txManager" 引入增强的类
何地:在哪些类的哪些方法中:pointcut
何时:在方法执行之前:before
做什么事:执行txManager这个bean中的方法
-->
<aop:aspect ref="txManager">
<!-- 前置通知 -->
<aop:before method="begin" pointcut-ref="pointcut"></aop:before>
<!-- 后置通知 -->
<aop:after-returning method="commit" pointcut-ref="pointcut"></aop:after-returning>
<!-- 异常通知(异常抛出去才能使用) -->
<aop:after-throwing method="rollback" pointcut-ref="pointcut" throwing="throwable"></aop:after-throwing>
<!-- 最终通知 -->
<aop:after method="close" pointcut-ref="pointcut"></aop:after>
</aop:aspect>
</aop:config>
环绕通知
- 前面的4个通知就不用了,其他一样
事务管理器对象(模拟的)
public class TxManager {
public void begin(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交事务");
}
public void rollback(Throwable throwable){
System.out.println("回滚事务 原因 : " + throwable.getMessage());
}
public void close(){
System.out.println("关闭事务");
}
/*环绕通知*/
public void around(ProceedingJoinPoint joinPoint){
try{
begin();
//执行方法
joinPoint.proceed();
commit();
}catch (Throwable throwable){
rollback(throwable);
throwable.printStackTrace();
}finally {
close();
}
}
}
xml配置
<aop:aspect ref="txManager">
<!--环绕通知(可以自己控制执行顺序)-->
<aop:around method="around" pointcut-ref="pointcut"></aop:around>
</aop:aspect>
(二)注解版实现AOP
- 需要在相应的bean上加注解
- 配置包的扫描
- 所有的配置都是在TxManager加注解
xml配置
<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
">
<!--开启扫描包-->
<context:component-scan base-package="com.lty._02aopanno"></context:component-scan>
<!--支持AOP注解-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
事务管理器TxManager
- 切点的名字是方法名()
/**
* @Aspect = <aop:aspect ref="txManager">
*/
@Component
@Aspect
public class TxManager {
/*配置一个切点(随便写个方法)
*<aop:pointcut id="pointcut()" expression="execution()"></aop:pointcut>
*/
@Pointcut("execution(* com.lty._02aopanno.service.I*Service.*(..))")
public void pointcut(){
}
/*<aop:before method="begin" pointcut-ref="pointcut"></aop:before>*/
@Before("pointcut()")
public void begin(){
System.out.println("开启事务");
}
/*<aop:after-returning method="commit" pointcut-ref="pointcut"></aop:after-returning>*/
@AfterReturning("pointcut()")
public void commit(){
System.out.println("提交事务");
}
/*<aop:after-throwing method="rollback" pointcut-ref="pointcut" throwing="throwable"></aop:after-throwing>*/
@AfterThrowing(value = "pointcut()",throwing = "throwable")
public void rollback(Throwable throwable){
System.out.println("回滚事务 原因 : " + throwable.getMessage());
}
/*<aop:after method="close" pointcut-ref="pointcut"></aop:after>*/
@After("pointcut()")
public void close(){
System.out.println("关闭事务");
}
}
环绕通知
- 要把其它几个通知的注解去掉(不然会出现重复)
/**
* @Aspect = <aop:aspect ref="txManager">
*/
@Component
@Aspect
public class TxManager {
public void pointcut(){}
public void begin(){
System.out.println("开启事务");
}
public void commit(){
System.out.println("提交事务");
}
public void rollback(Throwable throwable){
System.out.println("回滚事务 原因 : " + throwable.getMessage());
}
public void close(){
System.out.println("关闭事务");
}
/*环绕通知
*<aop:around method="around" pointcut-ref="pointcut"></aop:around>
*/
@Around("pointcut()")
public void around(ProceedingJoinPoint joinPoint){
try {
begin();
joinPoint.proceed();
commit();
}catch (Throwable throwable){
rollback(throwable);
throwable.printStackTrace();
}finally {
close();
}
}
}
6532

被折叠的 条评论
为什么被折叠?



