Spring AOP - 引入增强 - 利用一个开关控制是否进行性能监控

实现原理:

引起增强完成功能:
引入增强是一种比较特殊的增强类型,不是在目标方法周围植入增强,而是为目标类创建新的方法和属性所以引入增强的连接点是类级别的,而非方法级别
通过引入增强,我们可以为目标类添加一个接口的实现(即目标类可能为实现的接口),通过引入增强代理实现新的功能

例如实现:一个开关控制利用一个开关控制是否进行性能监控
1. 定义开关监控接口 Monitor
2. 定义实现类ControllablePerformanceMonitor继承DelegatingIntroductionInterceptor并实现接口Monitor
3. 定义ThreadLocal变量用于存储开关的值
4. 重写函数 invoke 并根据开关的值来决定是否调用嵌入的性能监控逻辑
5. 配置XML

定义接口类

package com.advice;

import com.smart.domain.User;

import java.sql.SQLException;

/**
 * @author Duoduo
 * @version 1.0
 * @date 2017/4/22 18:58
 */
public interface IUserDao {
    int addUser(User user);
    int updateUser(User user);
    void deleteUser(User user);
    void removeUser(User user) throws SQLException;
}

接口实现类

package com.advice;

import com.smart.domain.User;

import java.sql.SQLException;

/**
 * @author Duoduo
 * @version 1.0
 * @date 2017/4/22 19:00
 */
public class UserDaoImpl implements IUserDao {
    @Override
    public int addUser(User user) {
        System.out.println("Add user");
        return 0;
    }

    @Override
    public int updateUser(User user) {
        System.out.println("Update user");
        return 0;
    }

    @Override
    public void deleteUser(User user) {
        //throw new RuntimeException("exception test");
    }

    @Override
    public void removeUser(User user) throws SQLException {
        //throw new SQLException("SQLException Test");
    }
}

定义新增开关功能的接口

package com.advice;

/**
 * @author Duoduo
 * @version 1.0
 * @date 2017/4/23 11:20
 */
public  interface Monitor {
    void setMonitorActive(boolean active);
}

定义引入增强类

package com.advice;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;

/**
 * 引入增强:
 *   是一种比较特殊的增强类型,不是在目标方法周围植入增强,而是为目标类创建新的方法和属性
 *   所以引入增强的连接点是类级别的,而非方法级别
 *
 *   通过引入增强,我们可以为目标类添加一个接口的实现(即目标类可能为实现的接口),通过引入增强代理实现新的功能
 *
 * @author Duoduo
 * @version 1.0
 * @date 2017/4/23 11:21
 */
public class ControllablePerformanceMonitor extends DelegatingIntroductionInterceptor implements Monitor {

    //当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
    //所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
    private ThreadLocal<Boolean> monitorStatus = new ThreadLocal<Boolean>();

    @Override
    public void setMonitorActive(boolean active) {
        monitorStatus.set(active);
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object object = null;

        Boolean active = monitorStatus.get();

        if (active != null && active) {
            System.out.println("Performance monitor start ..... for method "+ mi.getMethod().getName());
            object = super.invoke(mi);
            System.out.println("Performance monitor end ..... for method "+ mi.getMethod().getName());

        }else{
            object = super.invoke(mi);
        }

        return object;
    }
}

Spring XML 配置

特别注意:代理工厂是 ProxyFactoryBean 不是 ProxyFactory

<bean id="performanceMonitor" class="com.advice.ControllablePerformanceMonitor"/>
<bean id="userDaoProxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean"
      p:interfaces="com.advice.Monitor"
      p:target-ref="userDaoImpl"
      p:interceptorNames="performanceMonitor"
      p:proxyTargetClass="true"/>

Junit测试类

@Test
    public void introductionTest(){

        System.out.println("************ introductionTest start *************");
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-another-context.xml");

        //获取代理类
        UserDaoImpl userDaoProxyFactory = (UserDaoImpl)context.getBean("userDaoProxyFactory");

        System.out.println("========= set monitor true ============");

        Monitor monitor = (Monitor)userDaoProxyFactory;
        monitor.setMonitorActive(true);
        userDaoProxyFactory.addUser(user);

        System.out.println("========= set monitor false ============");
        monitor.setMonitorActive(false);
        userDaoProxyFactory.addUser(user);



        System.out.println("************ introductionTest end *************");

    }

测试结果

========= set monitor true ============
Performance monitor start ..... for method addUser
Add user
Performance monitor end ..... for method addUser
========= set monitor false ============
Performance monitor start ..... for method setMonitorActive
Performance monitor end ..... for method setMonitorActive
Add user
************ introductionTest end *************
************ addUserAdivceTest ************
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值