Spring的AOP

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();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值