一:概念
Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题。AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。比如我们最常见的就是日志记录了,举个例子,我们现在提供一个查询学生信息的服务,但是我们希望记录有谁进行了这个查询。如果按照传统的OOP的实现的话,那我们实现了一个查询学生信息的服务接口(StudentInfoService)和其实现 类 (StudentInfoServiceImpl.java),同时为了要进行记录的话,那我们在实现类(StudentInfoServiceImpl.java)中要添加其实现记录的过程。这样的话,假如我们要实现的服务有多个呢?那就要在每个实现的类都添加这些记录过程。这样做的话就会有点繁琐,而且每个实现类都与记录服务日志的行为紧耦合,违反了面向对象的规则。那么怎样才能把记录服务的行为与业务处理过程中分离出来呢?看起来好像就是查询学生的服务自己在进行,但却是背后日志记录对这些行为进行记录,并且查询学生的服务不知道存在这些记录过程,这就是我们要讨论AOP的目的所在。AOP的编程,好像就是把我们在某个方面的功能提出来与一批对象进行隔离,这样与一批对象之间降低了耦合性,可以就某个功能进行编程。
二:基本信息
Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题。AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。 [1] 比如我们最常见的就是日志记录了,举个例子,我们现在提供一个服务查询学生信息的,但是我们希望记录有谁进行了这个查询。如果按照传统的OOP的实现的话,那我们实现了一个查询学生信息的服务接口(StudentInfoService)和其实现类(StudentInfoServiceImpl.java),同时为了要进行记录的话,那我们在实现类(StudentInfoServiceImpl.java)中要添加其实现记录的过程。这样的话,假如我们要实现的服务有多个呢?那就要在每个实现的类都添加这些记录过程。这样做的话就会有点繁琐,而且每个实现类都与记录服务日志的行为紧耦合,违反了面向对象的规则。那么怎样才能把记录服务的行为与业务处理过程中分离出来呢?看起来好像就是查询学生的服务自己在进行,但却是背后日志记录对这些行为进行记录,并且查询学生的服务不知道存在这些记录过程,这就是我们要讨论AOP的目的所在。AOP的编程,好像就是把我们在某个方面的功能提出来与一批对象进行隔离,这样与一批对象之间降低了耦合性,可以就某个功能进行编程。
三:代码分析
接口实现方案
public interface StudentInfoService{
void findInfo(String studentName);
}
及其实现类(StudentInfoServiceImpl.java):
public class StudentInfoServiceImpl implements StudentInfoService{
public void findInfo(String name){
System.out.println("你目前输入的名字是:"+name);
}
}
import org.apache.log4j.Logger;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
public class MyHandler implements InvocationHandler{
private Object proxyObj;
private static Logger log=Logger.getLogger(MyHandler.class);
public Object bind(Object obj){
this.proxyObj=obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
Object result=null;
try{
//请在这里插入代码,在方法前调用
("调用log日志方法"+method.getName());
result=method.invoke(proxyObj,args); //原方法
//请在这里插入代码,方法后调用
}catch(Exception e){
e.printStackTrace();
}
return result;
}
}
2'我们实现一个工厂,为了方便我们使用该拦截类(AOPFactory.java):
public class AOPFactory{
private static Object getClassInstance(String clzName){
Object obj=null;
try{
Class cls=Class.forName(clzName);
obj=(Object)cls.newInstance();
}catch(ClassNotFoundException cnfe){
System.out.println("ClassNotFoundException:"+cnfe.getMessage());
}catch(Exception e){
e.printStackTrace();
}
return obj;
}
public static Object getAOPProxyedObject(String clzName){
Object proxy=null;
MyHandler handler=new MyHandler();
Object obj=getClassInstance(clzName);
if(obj!=null) {
proxy=handler.bind(obj);
}else{
System.out.println("Can't get the proxyobj");
//throw
}
return proxy;
}
}
3)基本的拦截与其工厂我们都实现了,现在测试(ClientTest.java):
public class ClientTest{
public static void main(String[] args){
StudentInfoService studentInfo= (StudentInfoService)AOPFactory.getAOPProxyedObject("StudentInfoServiceImpl");
studentInfo.findInfo("阿飞");
}
}
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
子类实现方案
public class StudentInfoServiceImpl{
public void findInfo(String name){
System.out.println("你目前输入的名字是:"+name);
}
}
2)实行一个工具来处理日志功能(AOPInstrumenter.java):
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
public class AOPInstrumenter implements MethodInterceptor{
private Logger log=Logger.getLogger(AOPInstrumenter.class);
private Enhancer enhancer=new Enhancer();
public Object getInstrumentedClass(Class clz){
enhancer.setSuperclass(clz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object o,Method method,Object[] args,MethodProxy proxy) throws Throwable{
("调用日志方法"+method.getName());
Object result=proxy.invokeSuper(o,args);
return result;
}
}
3)我们来测试一下(AOPTest.java):
public class AOPTest{
public static void main(String[] args){
AOPInstrumenter instrumenter=new AOPInstrumenter();
StudentInfoServiceImpl studentInfo=(StudentInfoServiceImpl)instrumenter.getInstrumentedClass(StudentInfoServiceImpl.class);
studentInfo.findInfo("阿飞");
}
}
本文详细介绍了面向切面编程(AOP)的概念及其在Java中的应用方式,通过实例展示了如何利用AOP分离关注点,降低代码耦合度,提高复用性和可维护性。

114

被折叠的 条评论
为什么被折叠?



