spring--------------->AOP
AOP:
面向切面编程,当有其它的业务需求的时候,比如添加日志等。但是我们不能在原有的代码上添加,那样不能保证开闭原则。可以用代理的方法。
原有业务:
1 package com.spring.aop; 2 public class ArithmeticCalculatorImpl implements ArithmeticCalculator{ 3 4 @Override 5 public int add(int i, int j) { 6 int result=i+j; 7 return result; 8 } 9 10 @Override 11 public int sub(int i, int j) { 12 int result=i-j; 13 return result; 14 } 15 }
添加日志。
添加代理类:
package com.spring.aop; import java.lang.reflect.Method; import org.springframework.cglib.proxy.InvocationHandler; import org.springframework.cglib.proxy.Proxy; //动态代理 public class AriProxy { //要代理的对象 private ArithmeticCalculator target; public AriProxy(ArithmeticCalculator target){ this.target=target; } public ArithmeticCalculator getProxy(){ ArithmeticCalculator proxy =null; //代理对象由哪一个类加载器进行加载 ClassLoader loader=target.getClass().getClassLoader(); //代理对象的类型 Class [] interfaces=new Class[]{ArithmeticCalculator.class}; InvocationHandler h=new InvocationHandler() { /* * proxy:正在返回的那个代理对象, * method:正在被调用的方法 * args:调用方法时,传入的参数 * */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName=method.getName(); System.out.println("The method"+methodName+"begin with"); Object result=method.invoke(target, args); return result; } }; proxy=(ArithmeticCalculator)Proxy.newProxyInstance(loader, interfaces, h); return proxy; } }
测试:
public class Main { public static void main(String[] args) { ArithmeticCalculator target=new ArithmeticCalculatorImpl() ; ArithmeticCalculator proxy=new AriProxy(target).getProxy(); int result=proxy.add(1, 2); System.out.println("---->"+result); } }
这样还是很麻烦我们用AOP
只需要写一个切面类:
这是注解的形式:
public class Main { public static void main(String[] args) { ArithmeticCalculator target=new ArithmeticCalculatorImpl() ; ArithmeticCalculator proxy=new AriProxy(target).getProxy(); int result=proxy.add(1, 2); System.out.println("---->"+result); } }
在xml文件中配置
设置自动扫描
<context:component-scan base-package="com.spring.aop2"></context:component-scan>
使AspjectJ注解起作用:自动匹配的类生成代理对象
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
用xml文件的形式:
<!-- 配置切面的bean -->
<bean id="LoggingAspect" class="com.spring.aop2.LogginAspect"></bean>
<!-- 配置AOP -->
<aop:config>
<aop:pointcut expression="execution(public int com.spring.aop2.ArithmeticCalculator.add(int,int))" id="pointcut"/>
<aop:aspect ref="LoggingAspect">
<aop:before method="beforeMethod" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
接下来弄懂AOP的各个组成:
验证 |
add() |
日志 |
验证和 日志:就是切面 add()方法就是目标 通知:切面完成的工作,也就是切面每一个方法 代理:向目标对象应用通知之后创建的对象。
连接点:程序执行的某个特定位置。比如方法调用前后,抛出异常等。
切点:连接点在程序中客观存在的事务。连接点相当于数据库中的记录。切点就相当于查询的条件。
需要用到的代理jar包