动态代理模式java中原生的实现方式
public static void main(String[] args) {
Hello hello = (Hello) Proxy.newProxyInstance(
ClassLoader.getSystemClassLoader() ,//指定代理对象的类加载器
new Class<?>[]{Hello.class},//代理对象需要实现的接口,可以指定多个
new LogInvocationHandle( new HelloImp()) );//调用实际处理者
System.out.println(hello.sayHello("hhhh:::"));
}
interface Hello{
String sayHello(String str);
}
class HelloImp implements Hello{
@Override
public String sayHello(String str) {
return "HelloImp "+str;
}
}
/**
* 静态代理类,打印日志
*/
class StaticProxideHello implements Hello{
private Hello hello = new HelloImp();
@Override
public String sayHello(String str) {
System.out.println("log_info");
return hello.sayHello(str);
}
}
class LogInvocationHandle implements InvocationHandler{
//核心:=================>通过反射获取object信息
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("sayHello".equals(method.getName())){
System.out.println("You said :" + Arrays.toString(args));
}
return method.invoke(hello,args);
}
private Hello hello;
public LogInvocationHandle(Hello hello){
this.hello = hello;
}
}
在spring中使用注解实现还是很方便的,
@Aspect
//代表这是个代理切片类(ps:此切片非golang中的数组)
@Component//注入容器之后使用上要理解一些spring容器管理原理,
public class LogAspect {
@Pointcut("@annotation(com.example.demo.aop.Action)")
public void annotationPointCut() {
}
//after表示先执行方法,后拦截,before表示先拦截,后执行方法
//
@Before("annotationPointCut()")
@After("annotationPointCut()")
public void after(JoinPoint joinPoint) {
//JoinPoint包含了很多原执行对象的信息,可以获取到传参返回结果等等,
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Action action = method.getAnnotation(Action.class);
System.out.println("注解式拦截:"+action.name());
}
/**
* 第一个星号表示返回类型,×表示所有类型,注意第一个星号和包名之间有空格
* 后面的星号表示任意字符
* 两个点表示任意个参数
*
* @param joinPoint
*/
@Before("execution(* com.example.demo.aop.MethodService.*(..))")
public void before(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
System.out.println("方法规则式拦截:"+method.getName());
}
}
注解里面规则没有进行深入了解,记这些规则感觉还有很费脑子的,