AOP是指面向切面编程,横向重复,纵向提取。在最早接触AOP思想是从servlet开始的,代码如下,设置字符集,通过filter统一设置。
1 @Override2 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)3 throws IOException, ServletException {4 request.setCharacterEncoding("UTF-8");5 chain.doFilter(request, response);6 response.setCharacterEncoding("UTF-8");7 }
再有就是再学习Struts2框架时接触到的拦截器栈。有国际化,参数封装,模型驱动,异常等等拦截器。
接着就是Spring的AOP思想,先说结论,Spring的AOP思想是通过动态代理和cglib代理实现,前者优先。
动态代理解释:被代理的对象必须要实现接口,动态代理对象相当于这个接口的实现类,是对被代理对象的扩展。可以看出动态代理是由局限性的,要求被代理对象要实现某个接口。
cglib代理解释:是一个第三方代理,是对被代理对象的继承代理,从而进行扩展。
代码演示
定义接口
1 public interface UserService {2 void save();3 void delete();4 void update();5 void select();6 }
实现接口
1 public class UserServiceImpl implements UserService{ 2 @Override 3 public void save() { 4 System.out.println("调用dao的保存方法"); 5 } 6 7 @Override 8 public void delete() { 9 System.out.println("调用dao的删除方法");10 }11 12 @Override13 public void update() {14 15 System.out.println("调用dao的更新方法");16 }17 18 @Override19 public void select() {20 21 System.out.println("调用dao的查询方法");22 }23 }
动态代理演示
1 /** 2 * 动态代理 3 * @author 67471 4 * 5 */ 6 public class ProxyUservice implements InvocationHandler{ 7 private UserService userService; 8 9 public ProxyUservice(UserService userService) {10 super();11 this.userService = userService;12 }13 14 public UserService getUserviceProxy(){15 //获得代理对象16 UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUservice.class.getClassLoader(),17 UserServiceImpl.class.getInterfaces(),18 this);19 return userServiceProxy;20 }21 22 //要增强的内容23 @Override24 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {25 System.out.println("开启事务");26 Object invoke = method.invoke(userService, args);27 System.out.println("提交事务");28 return invoke;29 }30 }
测试代码
1 public class ProxyTest { 2 public static void main(String[] args) { 3 //获得代理对象 4 ProxyUservice proxyUservice = new ProxyUservice(new UserServiceImpl()); 5 UserService userviceProxy = proxyUservice.getUserviceProxy(); 6 userviceProxy.save(); 7 //判断代理对象是被代理对象类型 8 System.out.println(userviceProxy instanceof UserServiceImpl); 9 }10 }
结果
开启事务调用dao的保存方法提交事务false
cglib代理演示
ublic class Cglibproxy implements MethodInterceptor{ private UserServiceImpl usi; public Cglibproxy(UserServiceImpl usi) { super(); this.usi = usi; } public UserService getUserviceProxy(){ Enhancer en = new Enhancer();//生成代理对象的对象 en.setSuperclass(UserServiceImpl.class);//cglib代理是继承代理,需要我们指定父类,所以父类不要用final修饰 en.setCallback(this);//指定增强的内容 UserServiceImpl userServiceImplProxy = (UserServiceImpl) en.create();//创建代理对象 return userServiceImplProxy; } @Override public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("开启事务"); Object invoke = method.invoke(usi, arg2);//需要指定方法的参数和目标对象 System.out.println("提交事务"); return invoke; }}
测试代码
public class ProxyTest2 { public static void main(String[] args) { //获得代理对象 Cglibproxy cglibproxy = new Cglibproxy(new UserServiceImpl()); UserService userviceProxy = cglibproxy.getUserviceProxy(); userviceProxy.save(); //判断代理对象是被代理对象类型吗 System.out.println(userviceProxy instanceof UserServiceImpl); }}
结果:
开启事务调用dao的保存方法提交事务true