您的位置:首页 > 编程语言 > Java开发

使用Java动态代理实现简单AOP

2011-09-16 20:28 991 查看
今天看了下Java动态代理,写了些简单的代码,然后利用之前看过的关于控制反转的知识,简单的实现了一个AOP的model,下面贴出代码:
首先是接口Interface_MyClass

package com.proxy;

public interface Interface_MyClass {

public void myMethod();

}

接着便是Interface_MyClass接口的一个实现类MyClass

package com.proxy;

public class MyClass implements Interface_MyClass{

public MyClass(){

}
@Override
public void myMethod() {

System.out.println("我的方法正在被执行!");

}
}

动态代理类,该类必须实现InvocationHandler接口

package com.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.beforeMethod.BeforeMethod;
import com.beforeMethod.Interface_BeforeMethod;

public class DynamicProxy  implements InvocationHandler{

public Object targetObject;

public DynamicProxy(Object targetObject){

super();
this.targetObject = targetObject;

}

public static Object create(Object targetObject){

return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), new DynamicProxy(targetObject));
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

ApplicationContext actx=new FileSystemXmlApplicationContext("config.xml");
BeforeMethod bm = (BeforeMethod)actx.getBean("bm");
bm.Before();

Object obj = method.invoke(targetObject, args);
return obj;
}

}


接着便是切入逻辑,目的为将before方法切入到MyClass类的myMethod方法执行之前,首先是切入逻辑的公共接口Interface_BeforeMethod

package com.beforeMethod;

public interface Interface_BeforeMethod {

public void before();
}


接着是两个切入逻辑的具体实现类,当然,如果需要可以实现很多这样的类,当前置逻辑放生变化的时候只需要新增加一些类,然后修改配置文件方可;

package com.beforeMethod;

public class BeforeMethod_ImplA  implements Interface_BeforeMethod{

@Override
public void before() {

System.out.println("前置功能A被执行!");

}
}

package com.beforeMethod;

public class BeforeMethod_ImplB implements Interface_BeforeMethod{

@Override
public void before() {

System.out.println("前置功能B被执行!");
}
}

BeforeMethod类,该类主要是将切入逻辑进行简单的包装,可以理解为帮助实现功能的一个帮助类

package com.beforeMethod;

public class BeforeMethod {

private Interface_BeforeMethod ib;

public void setIb(Interface_BeforeMethod ib) {
this.ib = ib;
}
public void Before(){

this.ib.before();
}

}

 下面是测试类,ProxyTest

package com.proxy;

public class ProxyTest{

public static void main(String[] args) {

Interface_MyClass myclass;
myclass = (Interface_MyClass)DynamicProxy.create(new MyClass());
myclass.myMethod();
}
}

最后当然是配置文件config.xml

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd"> 
<beans> 
     <bean id="bm_A" class="com.beforeMethod.BeforeMethod_ImplA"></bean>
     <bean id="bm_B" class="com.beforeMethod.BeforeMethod_ImplB"></bean>
     <bean id = "bm" class = "com.beforeMethod.BeforeMethod" >
     <property name="ib">
     <ref bean = "bm_B"></ref>
  </property>
     </bean>
</beans>

ok,通过以上方式(记着导入相应的Spring包哈),就实现了一个简单的AOP,这样就可以通过新增类和修改配置文件,来达到从容面对需求改变的问题了。下面是改程序的运行结果

2011-9-16 20:09:47 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@b4d3d5: display name [org.springframework.context.support.FileSystemXmlApplicationContext@b4d3d5]; startup date [Fri Sep 16 20:09:47 CST 2011]; root of context hierarchy
2011-9-16 20:09:47 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from file [D:\workspace\proxyTest\config.xml]
2011-9-16 20:09:47 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
信息: Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext@b4d3d5]: org.springframework.beans.factory.support.DefaultListableBeanFactory@cdedfd
2011-9-16 20:09:47 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@cdedfd: defining beans [bm_A,bm_B]; root of factory hierarchy
前置功能B被执行!
我的方法正在被执行!


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息