简介
AOP(Aspect Orient Programming),也就是面向方面编程,作为面向对象编程的一种补充,相对于面向对象的编程,它更注重于对象层次结构方面的东西。 与传统的OOP纵向编程思想相比,AOP更强调横向编程,AOP的出现恰恰就是对OOP出了完美的补充。在事务管理、安全检查、缓存、对象池管理等,AOP已经成为一种非常常用的解决方案。
利用动态代理实现AOP
在使用Spring实现AOP之前,先看一下静态代理,已经Java的动态代理。
(一) 静态代理:
包图
利用,代理接口(Subject)、代理类(ProxySubject)、委托类(RealSubject),现实对RealSubject的访问控制,由于静态代理比较简单,代码略。
静态代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成。
(二) 动态代理
接口类:
public interface UserManager {
public void addUser(String username, String password);
public void delUser(int userId);
public String findUserById(int userId);
public void modifyUser(int userId, String username, String password);
}
实现类:
public class UserManagerImpl implements UserManager {
public void addUser(String username, String password) {
//checkSecurity();
System.out.println("---------UserManagerImpl.add()--------");
}
public void delUser(int userId) {
//checkSecurity();
System.out.println("---------UserManagerImpl.delUser()--------");
}
public String findUserById(int userId) {
//checkSecurity();
System.out.println("---------UserManagerImpl.findUserById()--------");
return "张三";
}
public void modifyUser(int userId, String username, String password) {
//checkSecurity();
System.out.println("---------UserManagerImpl.modifyUser()--------");
}
代理生成类
public class SecurityHandler implements InvocationHandler {
private Object targetObject;
public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
checkSecurity();
//调用目标方法
Object ret = method.invoke(targetObject, args);
return ret;
}
private void checkSecurity() {
System.out.println("-------checkSecurity-------");
}
}
动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。AOP的实现有两种方式,动态代理为其中一种
Spring AOP的实例:
实现原理图:
普通类:
Package com.spring.aop;
public class Common {
public void execute(String username,String password){ System.out.println("------------------普通类----------------"); } }
切面类:
package com.spring.aop;
public class Check { public void checkValidity(){
System.out.println("------------------验证合法性----------------"); }
public void addLog(JoinPoint j){
System.out.println("------------------添加日志----------------"); Object obj[] = j.getArgs();
for(Object o :obj){ System.out.println(o); }
System.out.println("========checkSecurity=="+j.getSignature().getName());
配置:
<aop:config>
<aop:aspect id="myAop" ref="check">
<aop:pointcut id="target" expression="execution(* com.spring.aop.Common.execute(..))"/>
<aop:before method="checkValidity" pointcut-ref="target"/> <aop:after method="addLog" pointcut-ref="target"/> </aop:aspect> </aop:config>