记录一下自己对aop的理解,突然想起马士兵的对spring的模拟,解析xml文件使用java自带的sax或者是dom解析两种方式,得到类的名称然后使用反射来创建类。
aop是面向切面编程,可以说是面向对象编程的延续,基础原理是动态代理和反射,持有需要被代理类的对象然后再改对象调用方法之前或者之后加入,额外的功能。
代理分为proxy代理和cglib代理,细说是proxy代理只能代理接口cglib代理可以代理类,但是经过debug发现java用的都是cglib代理,这个问题留待以后查证 ,记录
proxy代理的具体使用方法
代理类:
//必须实现InvocationHandler接口
public class test implements InvocationHandler{
//所要代理的对象
Object target;
public test(Object obj){
this.obj=obj;
}
public void begin(){
System.out.println("method begin");
}
public void end(){
System.out.println("method end");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//在调用被代理对象之前所要进行的操作
begin();
method.invoke(target, args);
return null;
}
}
测试类:
public class Test {
public static void main(String []args){
//声明一个需要被代理的对象 这个对象必须是实现了接口!!!!
Logimpl l=new Logimpl();
//将被代理对象传入
test t=new test(l);
//将需要被代理的对象的classloader和interfaces还有代理的对象传入就能够在调用任何被代理对象的方法之前调用begin方法
Log l1=(Log)Proxy.newProxyInstance(l.getClass().getClassLoader(), l.getClass().getInterfaces(), t);
l1.begin();
}
}
aop的实现,xml方式
<!-- 需要将代理的类和被代理的类都注册为bean让spring进行管理-->
<bean id="test" class="com.zq.aop.test.test"></bean>
<bean id="Logimpl" class="com.zq.aop.log.Logimpl"></bean>
<!--配置一个aop需要三个要素1:需要知道那些对象或者对象的方法需要代理也就是被代理对象或者说 切点2:需要知道代理对象3:需要知道被代理对象在什么时候加入代理对象的元素,也就是在被代理对象方法执行之前还是之后执行代理对象的方法-->
<aop:config>
<aop:aspect ref="Logimpl">
<aop:pointcut expression="execution(* com.zq.aop.test.*.*(..))" id="pointcut"/>
<aop:before method="begin" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
测试类
public class Testdomain {
public static void main(String []args){
ApplicationContext c=new ClassPathXmlApplicationContext("applicationContext.xml");
test t=(test) c.getBean("test");
t.add();
}
}
aop的实现,annotation方式
//也是三要素:1:@Aspect把logimpl注册为了代理类2:@Before("execution(* com.zq.aop.test.*.*(..))")知道了在执行那些方法的之前,执行begin方法
@Component("Logimpl")
@Aspect
public class Logimpl {
@Before("execution(* com.zq.aop.test.*.*(..))")
public void begin() {
// TODO Auto-generated method stub
System.out.println("log begin");
}
public void end() {
// TODO Auto-generated method stub
System.out.println("log end");
}
}
annotation方式xml的配置
<!-- 开启自动代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 开启自动扫描 -->
<context:component-scan base-package="com.zq"></context:component-scan>