今天看了下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被执行!
我的方法正在被执行!