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

本文介绍如何使用Java动态代理实现AOP,并通过配置文件动态地添加前置逻辑,展示了如何灵活应对需求变更。
今天看了下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被执行!
我的方法正在被执行!


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值