今天的内容有点多,精简的讲一些我认为重要的东西
目录
什么是动态代理
我所理解的动态代理就是
就是像鸡蛋一样,其实真正所需要用的是蛋黄,所有不能直接调用,所以需要通过鸡蛋壳调用鸡蛋黄,最后在返回到鸡蛋壳上面,在返回到客户上,中间还有一些中间商,可以薅羊毛,在这件可以做一些逻辑,在调用鸡蛋黄之前调用加入逻辑,表示为前置通知,在此之后就表示为后置通知,都加上了就是环绕通知
动态代理的优势
实现无侵入式的代码扩展,也就是方法的增强
基于jdk动态代理实现
动态dialing的实现中有两个重要的类:InvocationHandler,Proxy
AOP的概念
连接点:程序过程中执行的点,方法的调用,或者异常的输出
package com.zking.spring.proxydemo;
public class SubjectImpl implements ISubject{
//连接点
//方法的集合就是切入点
@Override
public void hello(String param) {
// TODO Auto-generated method stub
System.out.println("hello"+param);
}
}
目标:被通知的代理对象
package com.zking.spring.proxydemo;
public class DKProxyDemo {
public static void main(String[] args) {
ISubject subject =new SubjectImpl();
//目标 被代理的那个就是目标
JDKProxy subjectProxy =new JDKProxy(subject);
ISubject proxy =(ISubject)subjectProxy.newProxy();
proxy.hello("猪八戒");
}
}
通知:Advice中的一个程序代码的实体表现
代理:将通知应用到目标对象,需要被代理的那个对象
package com.zking.spring.proxydemo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy implements InvocationHandler{
private Object target;
public JDKProxy(Object target) {
this.target =target;
}
//代理 动态的生成代理
public Object newProxy() {
return (ISubject)Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
}
切入点:多个连接点的集合
package com.zking.spring.proxydemo;
public class SubjectImpl implements ISubject{
//连接点
//方法的集合就是切入点
@Override
public void hello(String param) {
// TODO Auto-generated method stub
System.out.println("hello"+param);
}
}
适配器:通知+切入点,适配器相当于一个组织者
package com.zking.spring.proxydemo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy implements InvocationHandler{
private Object target;
public JDKProxy(Object target) {
this.target =target;
}
//代理 动态的生成代理
public Object newProxy() {
return (ISubject)Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
//适配器
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前置通知
System.out.println("----------在业务方法调用之前可以进行前置增强----------");
//利用反射机制调用方法,invoke为返回值,如果没有返回null
Object invoke =method.invoke(target, args);
//后置通知
System.out.println("---------在业务方法调用之前可以进行后置增强");
return invoke;
}
}
AOP带来的好处是试什么?
AOP是公用的框架代码放置的理想地方,将公共代码放置在AOP框架中,使公共代码与业务代码分离,可以让我们更专心的处理业务代码
前置通知,后置通知,环绕通知,异常通知,适配器示例代码
package com.zking.spring.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class MyAfterReturnAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] arges, Object target) throws Throwable {
// TODO Auto-generated method stub
System.out.println("[后置通知]:返利10元");
}
}
package com.zking.spring.advice;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.aop.MethodBeforeAdvice;
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
String s ="[前置通知]:"
+ this.getClass() +"."
+method.getName()
+"将被调用,参数为:"
+Arrays.toString(args);
System.out.println(s);
}
}
package com.zking.spring.advice;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
//获取目标对象
Object target =invocation.getThis();
//获取参数
Object[] args =invocation.getArguments();
//获取方法
Method method =invocation.getMethod();
System.out.print("[环绕通知] 前:将调用"+target.getClass()
+"."+method.getName()+"方法,参数为"+Arrays.toString(args));
Object rv =invocation.proceed();
System.out.println("[环绕通知] 后");
return rv;
}
}
package com.zking.spring.advice;
import java.util.logging.Logger;
import org.springframework.aop.ThrowsAdvice;
public class MyThrowAdvice implements ThrowsAdvice{
//异常通知
public void afterThrowing(PriceException e) {
System.out.println("程序发生了PriceException异常");
}
}