• Spring--基于代理类ProxyFactoryBean的AOP实现


    AOP—Aspect-oriented Programming

    面向方面编程。

    基于代理类的ProxyFactoryBean的AOP实现

    ProxyFactoryBean是FactoryBean接口的实现类。FactoryBean负责实例化一个Bean,

    <bean id="logAdvice" class="com.xue.aop.LogAdvice"></bean>
    ProxyFactoryBean负责创建代理实例,他内部使用FactoryBean来完成这一工作。使用这个是创建AOP的最基本的方式。
    例如
    数据访问层
    项目的Userao接口中声明两个方法
    public interface UserDao {
        public void addUser(String username,String password);
        public void delUser(int id);
    }

    UserDao的实现类:

    public class UserDaoImpl implements UserDao {
        @Override
        public void addUser(String username, String password) {
            System.out.println(username+"用户添加成功");
        }
    
        @Override
        public void delUser(int id) {
            System.out.println("编号为"+id+"的用户被删除");
        }
    }

    业务逻辑层:

    在UserBiz中,声明两个方法:

    public interface UserBiz {
        public void addUser(String username, String passworld);
    
        public void delUser(int id);
    }

    UserBiz的实现类:

    public class UserBizImpl implements UserBiz {
        UserDao userDao;
        //set方法用于依赖注入
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        @Override
        public void addUser(String username, String passworld) {
            userDao.addUser(username,passworld);
        }
    
        @Override
        public void delUser(int id) {
            userDao.delUser(id);
        }
    }

    方面代码:

    实现特定功能的方面代码在AOP概念中被称为“通知(Advice)”。通知分为前置通知、后置通知、环绕通知和异常通知。

    前置通知:(log4j的配置不做介绍)

    public class LogAdvice implements MethodBeforeAdvice {
        private Logger logger=Logger.getLogger(LogAdvice.class);
        @Override
        public void before(Method method, Object[] args, Object target) throws Throwable {
            //获取被调用的类名
            String targetClassname=target.getClass().getName();
            //获取被调用的方法名
            String targetMethodname=method.getName();
            String logInfoText="前置通知:"+targetClassname+"类的"+targetMethodname+"方法开始执行";
            logger.info(logInfoText);
        }
    }

    配置ApplicationContext.xml文件:

        <bean id="userDao" class="com.xue.dao.UserDaoImpl"></bean>
        <bean id="userBiz" class="com.xue.dao.UserBizImpl">
            <property name="userDao" ref="userDao"></property>
        </bean>
        <bean id="logAdvice" class="com.xue.aop.LogAdvice"></bean>
        <!--使用spring代理工厂定义一个代理,通过他访问业务类中的方法-->
        <bean id="ub" class="org.springframework.aop.framework.ProxyFactoryBean">
            <!--指定代理接口-->
            <property name="proxyInterfaces">
                <value>com.xue.dao.UserBiz</value>
            </property>
            <!--指定通知-->
            <property name="interceptorNames">
                <list>
                    <value>logAdvice</value>
                </list>
            </property>
            <!--指定目标对象-->
            <property name="target" ref="userBiz"></property>
        </bean>

    测试类:

    public class Test {
    
        public static void main(String[] args) {
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
            UserBiz userBiz= (UserBiz) context.getBean("ub");
            userBiz.addUser("zhangsan","123");
            userBiz.delUser(1);
        }
    }

    总结:虽然没有看过源码,但个人感觉,测试类中UserBiz通过getBean(“ub”)获取实例,是ProxyFactoryBean会自动在配置的xml中返回实例,并且让指定的通知在方法执行前执行。

    LogAdvice(指定的通知)做的事:获取类名、方法名,将其写入日志中。

    结果:

    [INFO ] [18:02:32] com.xue.aop.LogAdvice - 前置通知:com.xue.dao.UserBizImpl类的addUser方法开始执行
    zhangsan用户添加成功
    [INFO ] [18:02:32] com.xue.aop.LogAdvice - 前置通知:com.xue.dao.UserBizImpl类的delUser方法开始执行
    编号为1的用户被删除

     
  • 相关阅读:
    Python 自动化测试实战训练营,由浅入深,从小白到测试高手!
    接口测试 Mock 实战(二) | 结合 jq 完成批量化的手工 Mock
    从文科生转行测试,再到大厂测试开发工程师,我是如何做到的?
    严正声明|严厉打击盗版侵权、非法销售「霍格沃兹测试学院」课程的违法行为
    「金羽毛」有奖征文 | 记录测试开发技术进阶之路的点滴
    测试工程师职业发展漫谈
    Workshop 深圳站|实战+源码架构剖析带你揭开Appium的神秘面纱
    那些难改的 Bug,最后都怎样了?
    BAT大厂都在用的Docker。学会这三招,面试、工作轻松hold住
    2021 开年学习送福利,助力测试进阶提升!
  • 原文地址:https://www.cnblogs.com/neu-student/p/6567854.html
Copyright © 2020-2023  润新知