Spring AOP (3) - 環繞增強 實現

實現原理:

環繞增強完成功能:在目標類的方法執行前後嵌入增強邏輯.
實現原理:
1. 實現接口 MethodInterceptor,重寫函數 invoke ,在函數 invoke 前後實現需要插入目標方法之後的邏輯代碼
2. 利用ProxyFactoryBean代理類調用目標類方法
3.配置Spring 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;

import com.smart.domain.User;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * 環繞增強: 在目標類的方法前後嵌入增強邏輯
 * @author Duoduo
 * @version 1.0
 * @date 2017/4/23 09:59
 */
public class AddUserInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        //獲取參數
        Object[] args = invocation.getArguments();
        User user = (User)args[0];

        //在目標類執行方法之前執行 ...
        System.out.println("AddUserInterceptor before execute add user");

        //執行目標類的方法
        Object object = invocation.proceed();

        //在目標類執行方法之後執行 ...
        System.out.println("AddUserInterceptor after execute add user");

        return object;
    }
}

Spring XML 配置

特別注意:代理工廠是 ProxyFactoryBean 不是 ProxyFactory

<!-- 代理設置 -->
<bean id="userDaoImpl" class="com.advice.UserDaoImpl"/>
<bean id="addUserBeforAdvice" class="com.advice.AddUserBeforAdvice"/>
<bean id="addUserAfterAdvice" class="com.advice.AddUserAfterAdvice"/>
<bean id="addUserInterceptor" class="com.advice.AddUserInterceptor"/>

<bean id="addUserProxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean"
      p:proxyInterfaces="com.advice.IUserDao"
      p:target-ref="userDaoImpl"
      p:interceptorNames="addUserInterceptor"/>

兩種調用方式:
1.根據XML配置來進行調用測試
2.自己創建代理來進行測試

另種方法都需要注意:此處代理獲取的是代理Bean,指向的是Interface的代理。

@Test
public  void addUserInterceptorTest(){
    System.out.println("************ addUserInterceptorTest ************");

    /*IUserDao userDao = new UserDaoImpl();
    MethodInterceptor interceptor = new AddUserInterceptor();

    //創建代理工廠
    ProxyFactory proxyFactory = new ProxyFactory();
    //設置代理目標類
    proxyFactory.setTarget(userDao);

    //爲代理添加增強
    proxyFactory.addAdvice(interceptor);
    //生成代理實例
    IUserDao proxyUserDao = (IUserDao)proxyFactory.getProxy();

    proxyUserDao.addUser(user);*/
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-another-context.xml");
    //代理爲指向Interface的代理
    IUserDao userDaoProxyFactory = (IUserDao) context.getBean("addUserProxyFactory");
    userDaoProxyFactory.addUser(user);
}

測試結果

四月 23, 2017 3:43:28 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@d4342c2: startup date [Sun Apr 23 15:43:28 CST 2017]; root of context hierarchy
四月 23, 2017 3:43:28 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring-another-context.xml]

AddUserInterceptor before execute add user
Add user
AddUserInterceptor after execute add user
發佈了54 篇原創文章 · 獲贊 15 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章