AOP:Aspect Oriented Programming 面向切面编程
AOP,可以通过预编译方式和运行其动态代理实现在不修改源代码的情况下给程序动态统一添加某种特定功能的一种技术。也是Spring的两大特色IOC(Inversion of Controler控制反转)和AOP之一.
Spring中提供了四种实现AOP的方式:实现Spring提供的AOP接口
1.JDK提供的代理方式(又分为静态和动态)
2.原生Spring API接口
3.Spring纯配置方式
4.Spring注解
一.使用JDK提供的代理方式(此种方式不依赖于Spring框架)
1.1静态代理
我们通过一个小女孩去看电影的生活案例来说明,上源码~
interface GoOut,先把案例抽象成接口:
package com.ndkj.StaticProxy;
/**女孩看电影的接口类*/
public interface GoOut {
9
public void lookMovie();
}
class AGril,在抽象接口的基础上具体出小女孩的类:
package com.ndkj.StaticProxy;
/**小女孩实现类*/
public class AGirl implements GoOut{
@Override
public void lookMovie() {
System.out.println("我要看电影~!!");
}
}
到这里就是我们完全不使用AOP思想进行类实现的流程,接下来就要开始进行AOP实现了,我们想在不改变AGril类的基础上,在女孩看电影前为女孩加上更加详细的步骤,例如先准备号money,先买一点零食(假设女孩去的电影院可以自己带零食~),先坐公交车…
Class Proxy,创建一个代理类,此类也需要实现小女孩的接口,它将帮助小女孩完成看电影中所有的工作:
package com.ndkj.StaticProxy;
/**代理类*/
public class Proxy implements GoOut{
//通过引入女孩类的方式实现类的关联
private AGirl AGirl;
@Override
public void lookMovie() {
takeMoney();
takeBus();
AGirl.lookMovie();
goHome();
}
//带上钱~
public void takeMoney(){
System.out.println("看电影前带上Money~!");
}
//坐大巴~
public void takeBus(){
System.out.println("坐公交车去看电影~");
}
//买一点吃的!
public void buySemeFood(){
System.out.println("看电影前买一些爆米花!");
}
//高高兴兴回家~~
public void goHome(){
System.out.println("今天的电影真好看~回家!!");
}
public Proxy() {
}
public Proxy(AGirl AGirl) {
this.AGirl = AGirl;
}
}
至此我们的准备工作已经做完了~可以放心让小女孩去看电影了!
Class LetsGo测试类:
package com.ndkj.StaticProxy;
/**测试*/
public class LetsGo {
public static void main(String[] args) {
AGirl AGirl = new AGirl();
//将AGril类导入到代理类中,全程让代理类帮我们实现
Proxy proxy = new Proxy(AGirl);
proxy.lookMovie();
}
}
No Bug,No Error:
2.2动态代理
在上面的静态代理中,每有一个新的类产生,我们都需要写一个代理类来代理,针对静态代理的弊端,我们使用动态代理.动态代理的实际实现类并不需要我们书写,我们通过写代理类的处理类来自动生成实际代理类,它区别于静态代理于此.
我们把之前的接口和类搬下来:
package com.ndkj;
/**极度抽象的接口*/
public interface GoOut{
public void lookMovie();
}
Class AGril:
package com.ndkj;
/**小女孩类*/
public class AGril implements GoOut {
@Override
public void lookMovie() {
System.out.println("我出去看电影~");
}
}
在使用动态代理时,我们的代理类需要实现InvocationHandler类,通过这个类来动态生成实际的代理类.上代码:
package com.ndkj;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//我们会使用这个类自动生成代理类,代替AGril类来完成小女孩看电影的全部操作
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private AGril aGril;
public void setRent