一、aop思想:
横向重复,纵向抽取
1、乱码
2、事务管理
3,action
二、spring能够为容器中管理的对象生成代理对象
1、spring能帮我们生成代理对象
2、spring实现aop的原理
(1)动态代理(优先)
被代理对象必须要实现接口,才能产生代理对象,如果没有接口将不能使用动态代理技术
(2)cglib代理
第三方代理技术,cglib,可以对任何类生成代理,代理的原理是对目标对象进行继承代理,如果
目标对象被final修饰,那么该类无法被cglib代理。
3,上代码
(1)接口
package cn.itcast.service; public interface UserService { void save(); void delete(); void update(); void find(); }
(2)实现类
package cn.itcast.service; public class UserServiceImpl implements UserService { @Override public void save() { System.out.println("保存用户!"); //int i = 1/0; } @Override public void delete() { System.out.println("删除用户!"); } @Override public void update() { System.out.println("更新用户!"); } @Override public void find() { System.out.println("查找用户!"); } }
(3)动态代理代码
//观光代码=>动态代理 public class UserServiceProxyFactory implements InvocationHandler { public UserServiceProxyFactory(UserService us) { super(); this.us = us; } private UserService us; public UserService getUserServiceProxy(){ //生成动态代理 UserService usProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(), UserServiceImpl.class.getInterfaces(), this); //返回 return usProxy; } @Override public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable { System.out.println("打开事务!"); Object invoke = method.invoke(us, arg2);//原方法 System.out.println("提交事务!"); return invoke; } }
测试:
@Test //动态代理 public void fun1(){ UserService us = new UserServiceImpl(); UserServiceProxyFactory factory = new UserServiceProxyFactory(us); UserService usProxy = factory.getUserServiceProxy(); usProxy.save(); //代理对象与被代理对象实现了相同的接口 //代理对象 与 被代理对象没有继承关系 //System.out.println(usProxy instanceof UserServiceImpl );//false }
结果:
打开事务! 保存用户! 提交事务!
(4)cglib代理
//观光代码=>cglib代理 public class UserServiceProxyFactory2 implements MethodInterceptor { public UserService getUserServiceProxy(){ Enhancer en = new Enhancer();//帮我们生成代理对象 en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理 en.setCallback(this);//代理要做什么 UserService us = (UserService) en.create();//创建代理对象 return us; } @Override public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable { //打开事务 System.out.println("打开事务!"); //调用原有方法 Object returnValue = methodProxy.invokeSuper(prxoyobj, arg); //提交事务 System.out.println("提交事务!"); return returnValue; } }
测试:
@Test public void fun2(){ UserServiceProxyFactory2 factory = new UserServiceProxyFactory2(); UserService usProxy = factory.getUserServiceProxy(); usProxy.save(); //判断代理对象是否属于被代理对象类型 //代理对象继承了被代理对象=>true //System.out.println(usProxy instanceof UserServiceImpl );//true }
结果:
打开事务! 保存用户! 提交事务!
三、AOP中的名词:
joinpoint(连接点):目标对象中,所有可以增强的方法
pointcut(切入点):目标对象,已经增强的方法
Advice(通知/增强):增强的代码等
Target(目标对象):被代理对象
weaving(织如):将通知应用带切入点的过程
Proxy(代理):将通知织如到目标对象之后,形成代理对象
aspect(切面):切入点+通知