- AOP是Aspect Oriented Programming的缩写,意思是面向方面编程,与OOP(Object Oriented Programming)面向对象编程对等,都是一种编程思想。
- 从OOP角度分析,我们关注业务的处理逻辑,是属于纵向的行为,从AOP角度分析,我们关注对象行为发生时的问题,是属于横向的行为。
- AOP 作用:
- 1 监控函数的调用
- 2 捕获异常发生
- 实际应用在:事务、安全、日志等横切关注。
- 两种实现AOP的方式:
- 1,JDK提供的动态代理实现
- //接口
- public interface UserBean
- {
- void getUser();
- void addUser();
- void updateUser();
- void deleteUser();
- }
- //原始实现类
- public class UserBeanImpl implements UserBean
- {
- private String user = null;
- public UserBeanImpl()
- {
- }
- public UserBeanImpl(String user)
- {
- this.user = user;
- }
- public String getUserName()
- {
- return user;
- }
- public void getUser()
- {
- System.out.println("this is getUser() method!");
- }
- public void setUser(String user)
- {
- this.user = user;
- System.out.println("this is setUser() method!");
- }
- public void addUser()
- {
- System.out.println("this is addUser() method!");
- }
- public void updateUser()
- {
- System.out.println("this is updateUser() method!");
- }
- public void deleteUser()
- {
- System.out.println("this is deleteUser() method!");
- }
- }
- //代理类
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import com.cignacmc.finance.bean.UserBeanImpl;
- public class UserBeanProxy implements InvocationHandler
- {
- private Object targetObject;
- public UserBeanProxy(Object targetObject)
- {
- this.targetObject = targetObject;
- }
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- UserBeanImpl userBean = (UserBeanImpl) targetObject;
- String userName = userBean.getUserName();
- Object result = null;
- //权限判断
- if(userName != null && !"".equals(userName))
- {
- result = method.invoke(targetObject, args);
- }
- return result;
- }
- }
- //测试类
- import java.lang.reflect.Proxy;
- import com.cignacmc.finance.bean.UserBean;
- import com.cignacmc.finance.bean.UserBeanImpl;
- import com.cignacmc.finance.proxy.UserBeanProxy;
- public class ProxyExe
- {
- public static void main(String[] args)
- {
- System.out.println("Proved.............");
- UserBeanImpl targetObject = new UserBeanImpl("Bob Liang");
- UserBeanProxy proxy = new UserBeanProxy(targetObject);
- //生成代理对象
- UserBean object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
- targetObject.getClass().getInterfaces(), proxy);
- object.addUser();
- System.out.println("NO Proved.............");
- targetObject = new UserBeanImpl();
- proxy = new UserBeanProxy(targetObject);
- //生成代理对象
- object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
- targetObject.getClass().getInterfaces(), proxy);
- object.addUser();
- }
- }
- 输出:
- Proved.............
- this is addUser() method!
- NO Proved.............
- 从上面这个例子可以成功拦截了调用的方法addUser()并对其做了相应的处理
- 2, 通过cglib创建代理类, 好处是不要求我们的目标对象实现接口
- //原始类
- public class ClientBean
- {
- private String name = null;
- public ClientBean()
- {
- }
- public ClientBean(String name)
- {
- this.name = name;
- }
- public void addClient()
- {
- System.out.println("this is addClient() method!");
- }
- public void deleteClient()
- {
- System.out.println("this is deleteClient() method!");
- }
- public void getClient()
- {
- System.out.println("this is getClient() method!");
- }
- public void updateClient()
- {
- System.out.println("this is updateClient() method!");
- }
- public String getClientName()
- {
- return name;
- }
- public void setClientName(String name)
- {
- this.name = name;
- }
- }
- //代理类
- import java.lang.reflect.Method;
- import com.cignacmc.finance.bean.ClientBean;
- import net.sf.cglib.proxy.Enhancer;
- import net.sf.cglib.proxy.MethodInterceptor;
- import net.sf.cglib.proxy.MethodProxy;
- public class CGLibProxy implements MethodInterceptor
- {
- private Object targetObject;
- public Object createProxyObject(Object targetObject)
- {
- this.targetObject = targetObject;
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(this.targetObject.getClass());
- enhancer.setCallback(this);
- return enhancer.create();
- }
- public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
- {
- ClientBean clientBean = (ClientBean)targetObject;
- String userName = clientBean.getClientName();
- Object result = null;
- if(userName != null && !"".equals(userName))
- {
- result = method.invoke(targetObject, args);
- }
- return result;
- }
- }
- //测试类
- import java.lang.reflect.Proxy;
- import com.cignacmc.finance.bean.ClientBean;
- import com.cignacmc.finance.bean.UserBean;
- import com.cignacmc.finance.bean.UserBeanImpl;
- import com.cignacmc.finance.proxy.CGLibProxy;
- import com.cignacmc.finance.proxy.UserBeanProxy;
- public class ProxyExe
- {
- public static void main(String[] args)
- {
- System.out.println(".............CGLIB Proxy....................");
- System.out.println("Proved....................");
- CGLibProxy cproxy = new CGLibProxy();
- ClientBean clientBean = (ClientBean)cproxy.createProxyObject(new ClientBean("Bob Liang"));
- clientBean.addClient();
- System.out.println("NO Proved....................");
- cproxy = new CGLibProxy();
- clientBean = (ClientBean)cproxy.createProxyObject(new ClientBean());
- clientBean.addClient();
- }
- }
- 输出:
- .............CGLIB Proxy....................
- Proved....................
- this is addClient() method!
- NO Proved....................
- 切面(Aspect):对横切关注点的抽象(类似类对对象的抽象)
- 连接点(JoinPoint):被拦截到的点,泛指方法
- 切入点(CutPoint):对哪些连接点进行拦截的定义
- 通知(Advice):在特定的连接点,AOP框架执行的动作.前置/后置/例外/最终/环绕通知(调用方法之前执行,全部执行完毕之后)
- 引入(Introduction): 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified接口,来简化缓存。
- 目标对象(Target Object): 包含连接点的对象。也被称作 被通知或被代理对象。
- AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
- 织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时 完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样, 在运行时完成织入。
- AOP是Aspect Oriented Programming的缩写,意思是面向方面编程,与OOP(Object Oriented Programming)面向对象编程对等,都是一种编程思想。
- 从OOP角度分析,我们关注业务的处理逻辑,是属于纵向的行为,从AOP角度分析,我们关注对象行为发生时的问题,是属于横向的行为。
- AOP 作用:
- 1 监控函数的调用
- 2 捕获异常发生
- 实际应用在:事务、安全、日志等横切关注。
- 两种实现AOP的方式:
- 1,JDK提供的动态代理实现
- //接口
- public interface UserBean
- {
- void getUser();
- void addUser();
- void updateUser();
- void deleteUser();
- }
- //原始实现类
- public class UserBeanImpl implements UserBean
- {
- private String user = null;
- public UserBeanImpl()
- {
- }
- public UserBeanImpl(String user)
- {
- this.user = user;
- }
- public String getUserName()
- {
- return user;
- }
- public void getUser()
- {
- System.out.println("this is getUser() method!");
- }
- public void setUser(String user)
- {
- this.user = user;
- System.out.println("this is setUser() method!");
- }
- public void addUser()
- {
- System.out.println("this is addUser() method!");
- }
- public void updateUser()
- {
- System.out.println("this is updateUser() method!");
- }
- public void deleteUser()
- {
- System.out.println("this is deleteUser() method!");
- }
- }
- //代理类
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import com.cignacmc.finance.bean.UserBeanImpl;
- public class UserBeanProxy implements InvocationHandler
- {
- private Object targetObject;
- public UserBeanProxy(Object targetObject)
- {
- this.targetObject = targetObject;
- }
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
- {
- UserBeanImpl userBean = (UserBeanImpl) targetObject;
- String userName = userBean.getUserName();
- Object result = null;
- //权限判断
- if(userName != null && !"".equals(userName))
- {
- result = method.invoke(targetObject, args);
- }
- return result;
- }
- }
- //测试类
- import java.lang.reflect.Proxy;
- import com.cignacmc.finance.bean.UserBean;
- import com.cignacmc.finance.bean.UserBeanImpl;
- import com.cignacmc.finance.proxy.UserBeanProxy;
- public class ProxyExe
- {
- public static void main(String[] args)
- {
- System.out.println("Proved.............");
- UserBeanImpl targetObject = new UserBeanImpl("Bob Liang");
- UserBeanProxy proxy = new UserBeanProxy(targetObject);
- //生成代理对象
- UserBean object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
- targetObject.getClass().getInterfaces(), proxy);
- object.addUser();
- System.out.println("NO Proved.............");
- targetObject = new UserBeanImpl();
- proxy = new UserBeanProxy(targetObject);
- //生成代理对象
- object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
- targetObject.getClass().getInterfaces(), proxy);
- object.addUser();
- }
- }
- 输出:
- Proved.............
- this is addUser() method!
- NO Proved.............
- 从上面这个例子可以成功拦截了调用的方法addUser()并对其做了相应的处理
- 2, 通过cglib创建代理类, 好处是不要求我们的目标对象实现接口
- //原始类
- public class ClientBean
- {
- private String name = null;
- public ClientBean()
- {
- }
- public ClientBean(String name)
- {
- this.name = name;
- }
- public void addClient()
- {
- System.out.println("this is addClient() method!");
- }
- public void deleteClient()
- {
- System.out.println("this is deleteClient() method!");
- }
- public void getClient()
- {
- System.out.println("this is getClient() method!");
- }
- public void updateClient()
- {
- System.out.println("this is updateClient() method!");
- }
- public String getClientName()
- {
- return name;
- }
- public void setClientName(String name)
- {
- this.name = name;
- }
- }
- //代理类
- import java.lang.reflect.Method;
- import com.cignacmc.finance.bean.ClientBean;
- import net.sf.cglib.proxy.Enhancer;
- import net.sf.cglib.proxy.MethodInterceptor;
- import net.sf.cglib.proxy.MethodProxy;
- public class CGLibProxy implements MethodInterceptor
- {
- private Object targetObject;
- public Object createProxyObject(Object targetObject)
- {
- this.targetObject = targetObject;
- Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(this.targetObject.getClass());
- enhancer.setCallback(this);
- return enhancer.create();
- }
- public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
- {
- ClientBean clientBean = (ClientBean)targetObject;
- String userName = clientBean.getClientName();
- Object result = null;
- if(userName != null && !"".equals(userName))
- {
- result = method.invoke(targetObject, args);
- }
- return result;
- }
- }
- //测试类
- import java.lang.reflect.Proxy;
- import com.cignacmc.finance.bean.ClientBean;
- import com.cignacmc.finance.bean.UserBean;
- import com.cignacmc.finance.bean.UserBeanImpl;
- import com.cignacmc.finance.proxy.CGLibProxy;
- import com.cignacmc.finance.proxy.UserBeanProxy;
- public class ProxyExe
- {
- public static void main(String[] args)
- {
- System.out.println(".............CGLIB Proxy....................");
- System.out.println("Proved....................");
- CGLibProxy cproxy = new CGLibProxy();
- ClientBean clientBean = (ClientBean)cproxy.createProxyObject(new ClientBean("Bob Liang"));
- clientBean.addClient();
- System.out.println("NO Proved....................");
- cproxy = new CGLibProxy();
- clientBean = (ClientBean)cproxy.createProxyObject(new ClientBean());
- clientBean.addClient();
- }
- }
- 输出:
- .............CGLIB Proxy....................
- Proved....................
- this is addClient() method!
- NO Proved....................
- 切面(Aspect):对横切关注点的抽象(类似类对对象的抽象)
- 连接点(JoinPoint):被拦截到的点,泛指方法
- 切入点(CutPoint):对哪些连接点进行拦截的定义
- 通知(Advice):在特定的连接点,AOP框架执行的动作.前置/后置/例外/最终/环绕通知(调用方法之前执行,全部执行完毕之后)
- 引入(Introduction): 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified接口,来简化缓存。
- 目标对象(Target Object): 包含连接点的对象。也被称作 被通知或被代理对象。
- AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
- 织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时 完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样, 在运行时完成织入。