动态代理
接口:
interface MyInteface {
public void say();
public void getNameToyou();
public void eat(String s);
}
实现接口的对象:
public class MyUser implements MyInteface{
public void say() {
System.out.println("Hello");
}
public void getNameToyou() {
System.out.println("my name is xxx");
}
public void eat(String s) {
System.out.println("我吃了"+s);
}
}
代理类:
public class MyProxy implements InvocationHandler {
private Object target;
public MyProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(target.getClass().getName()+"."+method.getName()+"--"+System.currentTimeMillis());
method.invoke(target, args);
System.out.println(target.getClass().getName()+"."+method.getName()+"--"+System.currentTimeMillis());
return null;
}
}
测试:
public class TestDynamicproxy {
public static void main(String[] args) {
MyUser user = new MyUser();
MyProxy proxy = new MyProxy(user);
MyInteface myproxy = (MyInteface) Proxy.newProxyInstance(user.getClass().getClassLoader(),
user.getClass().getInterfaces(),
proxy);
myproxy.eat("apple");
myproxy.say();
myproxy.getNameToyou();
}
}
aop是一种思想而不是一种技术。所以说,如果抛开spring,上面的动态代理甚至静态代理的例子也可以算是一种aop。
spring中的aop实现分为两种,基于动态代理的aop和基于AspectJ的aop,我在网上看了很多关于aop文章,很多没写清楚二者的区别,或者打着spring aop的标题然后开始讲aspectJ的使用。
什么是AspectJ?
在网上一搜一大片所谓AspectJ的用法,其实都是AspectJ的“切面语法”,只是AspectJ框架的冰山一角,AspectJ是完全独立于Spring存在的一个Eclipse发起的项目,官方关于AspectJ的描述是:
Eclipse AspectJ is a seamless aspect-oriented extension to the Java™ programming language. It is Java platform compatible easy to learn and use.
是的AspectJ甚至可以说是一门独立的语言,我们常看到的在spring中用的@Aspect注解只不过是Spring2.0以后使用了AspectJ的风格而已本质上还是Spring的原生实现,关于这点Spring的手册中有提及:
@AspectJ使用了Java 5的注解,可以将切面声明为普通的Java类。@AspectJ样式在AspectJ 5发布的AspectJ project部分中被引入。Spring 2.0使用了和AspectJ 5一样的注解,并使用AspectJ来做切入点解析和匹配。但是,AOP在运行时仍旧是纯的Spring AOP,并不依赖于AspectJ的编译器或者织入器(weaver)。
因此我们常用的org.aspectj.lang.annotation包下的AspectJ相关注解只是使用了AspectJ的样式,至于全套的AspectJ以及织入器,那完全是另一套独立的东西。