标签:流行 span 抽象 void logging div cat 4.0 com
为什么需要AOP?
需求加减乘除
package com.tanlei.spring.bean.Aop; public interface AtithmeticCalculator { int add(int i,int j); int sub(int i,int j); int mul(int i,int j); int div(int i,int j); }
package com.tanlei.spring.bean.Aop; public class AtithmeticCalculatorImpl implements AtithmeticCalculator{ @Override public int add(int i, int j) { System.out.println("the method add begin whith ["+i+","+j+"]"); int result=i+j; System.out.println("the method add end whith"+result); return result; } @Override public int sub(int i, int j) { System.out.println("the method sub begin whith ["+i+","+j+"]"); int result=i-j; System.out.println("the method sub end whith"+result); return result; } @Override public int mul(int i, int j) { System.out.println("the method mul begin whith ["+i+","+j+"]"); int result=i*j; System.out.println("the method mul end whith"+result); return result; } @Override public int div(int i, int j) { System.out.println("the method div begin whith ["+i+","+j+"]"); int result=i/j; System.out.println("the method div end whith"+result); return result; } }
package com.tanlei.spring.bean.Aop; public class Main { public static void main(String[] args) { AtithmeticCalculatorImpl aImpl=new AtithmeticCalculatorImpl(); aImpl.add(4, 8); aImpl.sub(4, 8); aImpl.mul(4, 8); aImpl.div(4, 8); } }
1.执行方法前后的日志
代码混乱
代码分散
使用动态代理解决上述问题
复杂动态代理代码(不推荐使用)
package com.tanlei.spring.bean.Aop; public interface AtithmeticCalculator { int add(int i,int j); int sub(int i,int j); int mul(int i,int j); int div(int i,int j); }
package com.tanlei.spring.bean.Aop; public class AtithmeticCalculatorImpl implements AtithmeticCalculator{ @Override public int add(int i, int j) { int result=i+j; return result; } @Override public int sub(int i, int j) { int result=i-j; return result; } @Override public int mul(int i, int j) { int result=i*j; return result; } @Override public int div(int i, int j) { int result=i/j; return result; } }
package com.tanlei.spring.bean.Aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; public class AtithmeticCalculatorLoggingProxy { // 要代理的对象 private AtithmeticCalculator target; public AtithmeticCalculatorLoggingProxy(AtithmeticCalculator target) { this.target = target; } public AtithmeticCalculator getLoggingProxy() { AtithmeticCalculator proxy = null; // 代理对象由哪一个类加载器负责 ClassLoader loader = target.getClass().getClassLoader(); // 代理对象的类型,即其中有哪些方法 Class[] interfaces = new Class[] { AtithmeticCalculator.class }; // 当调用代理对象其中的方法时,该执行的代码 InvocationHandler h = new InvocationHandler() { /** * proxy:正在返回的那个代理对象,一般情况下,在invoke方法中都不使用该对象 * method:正在被调用的方法 * args:调用方法时传人的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName=method.getName(); //日志 System.out.println("The method: "+methodName+"begins with"+Arrays.asList(args)); //执行方法 Object result=method.invoke(target, args); //日志 System.out.println("The method: "+methodName+"ends with"+result); return result; } }; proxy = (AtithmeticCalculator) Proxy.newProxyInstance(loader, interfaces, h); return proxy; } }
package com.tanlei.spring.bean.Aop; public class Main { public static void main(String[] args) { /*AtithmeticCalculatorLoggingImpl aImpl=new AtithmeticCalculatorLoggingImpl(); aImpl.add(4, 8); aImpl.sub(4, 8); aImpl.mul(4, 8); aImpl.div(4, 8);*/ AtithmeticCalculator target=new AtithmeticCalculatorImpl(); AtithmeticCalculator proxy=new AtithmeticCalculatorLoggingProxy(target).getLoggingProxy(); int result=proxy.add(1, 2); System.out.println(result); } }
简单的方法实现动态代理(AOP)
AOP基本概念
面向切面编程
在应用AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能在哪里,以什么方式应用,并且不必修改受影响的类,这样一来横切关注点就被模块化到特殊的对象(切面)里;
Aop的好处
每个事物处理逻辑位于一个位置,代码不分散,便于维护和升级
业务模块更简洁,只包含核心业务代码
AspectJ:java社区里最完整最流行的AOP框架
在Spring2.0版本上,可以使用基于AspectJ注解或基于XML配置的AOP
1.导入jar包:
aopalliance-.jar
aspectj.weaver.jar
spring-aspects.jar
2.要在Spring Ioc容器中启用AspectJ注解支持,只要在bean配置文件中定义一个空的XML元素<aop:aspectj-autoproxy>
3.当Spring IOC容器侦测到Bean配置文件中的<aop:aspectj-autoproxy>元素时,会自动为AspectJ切面匹配的Bean创建代理
小结:
1.Spring AOP 1).加入jar包 com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aop-4.0.0.RELEASE.jar spring-aspects-4.0.0.RELEASE.jar commons-logging-1.1.1.jar spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0.RELEASE.jar spring-core-4.0.0.RELEASE.jar spring-expression-4.0.0.RELEASE.jar 2).配置文件中加入Aop的命名空间 3)基于注解的方式 1.在配置文件中加入如下配置 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 2.把横切关注点的代码抽象到切面的类中 切面首先是一个IOC的bean,即加入@Componet注解 切面还需要加入@Aspect 注解 3.类中声明各种通知 @Before – 方法执行前运行 @After – 运行在方法返回结果后 @AfterReturning – 运行在方法返回一个结果后,在拦截器返回结果。 @AfterThrowing – 运行方法在抛出异常后, @Around – 围绕方法执行运行,结合以上这三个通知。 1.声明一个方法 2.在方法前加入@Before 3.在通知的方法里面可以加入连接点JoinPoint 访问方法的参数 如方法的签名和参数
对于Spring AOP 采用两种代理方法,一种是常规JDK,一种是CGLIB,我的UserDaoImpl实现了一个接口IUserDao,当代理对象实现了至少一个接口时,默认使用JDK动态创建代理对象,当代理对象没有实现任何接口时,就会使用CGLIB方法。由于UserDAOImpl实现了UserDAO接口,所以强制转换必须用父类UserDAO来定义
如果你的代理对象没有实现接口的方法,就将代理对象转换成接口。
获取代理类的代码该为:
ApplicationContext ctx =
new
ClassPathXmlApplicationContext(
"applicationContext.xml"
);
UserDao userDao = (UserDaoImpl)ctx.getBean(
"userDaoImpl"
);
标签:流行 span 抽象 void logging div cat 4.0 com
原文地址:https://www.cnblogs.com/tanlei-sxs/p/10140920.html