實現原理:
環繞增強完成功能:在目標類的方法執行前後嵌入增強邏輯.
實現原理:
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