关于AOP的一些认识

AOP是 Aspect Oriented Programming的缩写,即面向切面编程。
AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。比如我们最常见的就是日志记录了,举个例子,我们现在提供一个服务查询学生信息的,但是我们希望记录有谁进行了这个查询。如果按照传统的 OOP的实现的话,那我们实现了一个查询学生信息的服务接口(StudentInfoService)和其实现类(StudentInfoServiceImpl.java),同时为了要进行记录的话,那我们在实现类(StudentInfoServiceImpl.java)中要添加其实现记录的过程。这样的话,假如我们要实现的服务有多个呢?那就要在每个实现的类都添加这些记录过程。这样做的话就会有点繁琐,而且每个实现类都与记录服务日志的行为紧耦合,违反了面向对象的规则。那么怎样才能把记录服务的行为与业务处理过程中分离出来呢?看起来好像就是查询学生的服务自己在进行,但是背后日志记录对这些行为进行记录,但是查询学生的服务不知道存在这些记录过程,这就是我们要讨论AOP的目的所在。AOP的编程,好像就是把我们在某个方面的功能提出来与一批对象进行隔离,这样与一批对象之间降低了耦合性,可以就某个功能进行编程。
要实现以上的目标,我们可以使用一个动态代理类 (Proxy),通过拦截一个对象的行为并添加我们需要的功能来完成。Java中的java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口为我们实现动态代理类提供了一个方案,但是该方案针对的对象要实现某些接口。
接口的实现:
1)首先编写我们的业务接口StudentInfoService.java:
 
public interface StudentInfoService
{
    void findInfo(String studentName);
}
实现类 StudentInfoServiceImpl.java:

public class StudentInfoServiceImpl implements StudentInfoService
{
    public void findInfo(String name)
    {
        System.out.println("你目前输入的名字是:"+name);
    }
}
 
2)一个日志功能,在findInfo行为之前执行并记录其行为,那么我们就首先要拦截该行为。在实际执行的过程中用一个代理类来替我们完成。
1. 处理拦截目的的类MyHandler.java
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.info("调用log日志方法"+method.getName());
            result=method.invoke(proxyObj,args); //原方法
            //请在这里插入代码,方法后调用
        }catch(Exception e)
        {
            e.printStackTrace();
        }
        return result;
    }
}
 
2. 我们实现一个工厂,为了方便我们使用该拦截类 BeanFactory.java:
public class BeanFactory
{
    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");
        }
        return proxy;
    }
}
 
3. 测试 ClientTest.java:
public class ClientTest
{
    public static void main(String[] args)
    {
        StudentInfoService studentInfo=(StudentInfoService) BeanFactory.getAOPProxyedObject("StudentInfoServiceImpl");
        studentInfo.findInfo("Lynn");
    }
}
 
输出结果:
[INFO]调用log日志方法findInfo
你目前输入的名字是:Lynn
这样我们需要的效果就出来了,业务处理自己在进行,但是我们实现了日志功能,而业务处理(StudentInfoService)根本不知道存在该行为的。但是Java中提供的动态代理类的实现是针对实现了某些接口的类,如果没有实现接口的话,不能创建代理类。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值