Spring--基於代理類ProxyFactoryBean的AOP實現

AOP—Aspect-oriented Programming

面向方面編程。spring

基於代理類的ProxyFactoryBean的AOP實現

ProxyFactoryBean是FactoryBean接口的實現類。FactoryBean負責實例化一個Bean,編程

app

<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的實現類:ide

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中,聲明兩個方法:this

public interface UserBiz {
    public void addUser(String username, String passworld);

    public void delUser(int id);
}

UserBiz的實現類:spa

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的配置不作介紹)code

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的用戶被刪除

相關文章
相關標籤/搜索