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的用户被删除

 

 

 
posted @ 2017-03-17 18:37  LookOutTheBush  阅读(875)  评论(0编辑  收藏  举报