aop思想介绍
aop 思想精髓 【横向重复,纵向抽取】
举个简单的例子,原先我们使用servlet,多个servlet里面都要对乱码进行处理,我们就可以通过filter来解决这个问题。
spring中的aop概念
spring实现aop的原理
动态代理(优先)
被代理对象必须要实现接口,才能产生代理对象.如果没有接口将不能使用动态代理技术
看个例子
UserService 接口有增删改查4个接口
package cn.zdfy.b_proxy;
public interface UserService {
void save();
void del();
void update();
void find();
}
UserServiceImpl 具体实现这个接口的4个方法
开启事务的话,按照之前的代码,每个里面都需要像下面这样写
System.out.println("开启事务---");
System.out.println("save----------------------------");
System.out.println("提交事务---");
使用代理我们无需关心这些,事务管理可以公共抽取
package cn.zdfy.b_proxy;
public class UserServiceImpl implements UserService {
public void save() {
System.out.println("save----------------------------");
}
public void del() {
System.out.println("del----------------------------");
}
public void update() {
System.out.println("update----------------------------");
}
public void find() {
System.out.println("find----------------------------");
}
}
代理类 UserServiceFactory
package cn.zdfy.b_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserServiceFactory<T> implements InvocationHandler {
private T targetObj;
public UserServiceFactory(T targetObj) {
this.targetObj = targetObj;
}
/***
* 获取代理对象实例
*
* @return
*/
public T getInstance() {
return (T) Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(),
this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务-------------------------");
Object rv = method.invoke(targetObj, args);
System.out.println("提交事务-------------------------");
return rv;
}
}
测试代码 UserServiceTest
package cn.zdfy.b_proxy;
import org.junit.Test;
public class UserServiceTest {
@Test
public void fun1() {
UserService us = new UserServiceImpl();
UserService usiObj = (UserService) new UserServiceFactory<UserService>(us).getInstance();
usiObj.save();
usiObj.del();
usiObj.update();
usiObj.find();
}
}
测试结果
开启事务-------------------------
save----------------------------
提交事务-------------------------
开启事务-------------------------
del----------------------------
提交事务-------------------------
开启事务-------------------------
update----------------------------
提交事务-------------------------
开启事务-------------------------
find----------------------------
提交事务-------------------------
cglib代理(没有接口)
第三方代理技术,cglib代理.可以对任何类生成代理.代理的原理是对目标对象进行继承代理. 如果目标对象被final修饰.那么该类无法被cglib代理.
看例子
UserServiceFactory2
package cn.zdfy.b_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class UserServiceFactory2 implements MethodInterceptor {
private UserService targetObj;
public UserServiceFactory2(UserService targetObj) {
this.targetObj = targetObj;
}
/***
* 获取代理对象实例
*
* @return
*/
public UserService getInstance() {
// 生成代理对象
Enhancer en = new Enhancer();
// 设置对谁进行代理
en.setSuperclass(UserServiceImpl.class);
en.setCallback(this);
return (UserService) en.create();
}
public Object intercept(Object proxyObj, Method method, Object[] arg2, MethodProxy methodProxy) throws Throwable {
System.out.println("开启事务-------------------------");
Object rv = methodProxy.invokeSuper(proxyObj, arg2);
System.out.println("提交事务-------------------------");
return rv;
}
}
测试代码
@Test
public void fun2() {
UserService us = new UserServiceImpl();
UserServiceFactory2 factory = new UserServiceFactory2(us);
UserService usProxy = factory.getInstance();
usProxy.save();
usProxy.del();
usProxy.update();
usProxy.find();
System.out.println(
"usProxy instanceof UserServiceImp=================== " + (usProxy instanceof UserServiceImpl));
}
测试结果
开启事务-------------------------
save----------------------------
提交事务-------------------------
开启事务-------------------------
del----------------------------
提交事务-------------------------
开启事务-------------------------
update----------------------------
提交事务-------------------------
开启事务-------------------------
find----------------------------
提交事务-------------------------
true