AOP代码实现理解(三)

package Test2016.demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Date;

public class Demo5 {

    public static void main(String[] args) {
        
//        前期:
        /**
        AopService aopService = new AopServiceImpl();
        aopService.sayHello("JAVA");
        */
        
//        后期:
        AopService aopService = (AopService) new AopServiceLogImpl().bind(new AopServiceLogImpl(), new LoggerOperation());
        
        aopService.sayBye("JAVA");
        aopService.sayHello("JAVA");
    }
    
}


interface AopService {
    
    void sayHello(String name);
    
    void sayBye(String name);
    
}

class AopServiceImpl implements AopService{

    public void sayHello(String name) {
        System.out.println("Hello! " + name);
    }
    
    public void sayBye(String name) {
        System.out.println(name + "Bye!!!");
    }

    
}

class AopServiceLogImpl implements InvocationHandler {
    private Object proxy;
    private Object obj;

    public Object bind(Object obj, Object proxy) {
        this.obj = obj;
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), this.obj.getClass().getInterfaces(), this);
    }
    
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result = null;
        
        //反射得到操作者的实例
        Class<?> clazz = this.proxy.getClass();
        
        //反射得到操作者的Start方法 
        Method start = clazz.getDeclaredMethod("start", new Class<?>[] {Method.class});
        
        //反射执行start方法
        start.invoke(this.proxy, new Object[] {method});
        
        //执行要处理对象的原本方法
        result = method.invoke(this.obj, args);

        //反射得到操作者的end方法 
        Method end = clazz.getDeclaredMethod("end", new Class<?>[] {Method.class});
        
        //反射执行end方法
        end.invoke(this.proxy, new Object[] {method});
        
        return result;
    }
    
}


interface IOperation {
    void start(Method method);
    
    void end(Method method);
}

class LoggerOperation  implements IOperation {

    @Override
    public void end(Method method) {
        Logger.logging(Level.DEBUG, method.getName() + " method end.");
    }

    @Override
    public void start(Method method) {
        Logger.logging(Level.INFO, method.getName() + " method start.");    
    }
    
}

//日志类
class Logger {
    
    @SuppressWarnings("deprecation")
    public static void logging(Level level, String context) {
        if (Level.INFO.equals(level)) {
            System.out.println(new Date().toLocaleString() + " " + context);
        }
        
        if (Level.DEBUG.equals(level)) {
            System.out.println(new Date() + " " + context);
        }
    }
    
}

//枚举类
enum Level {
    INFO,DEBUG;
}

如果每个方法之后不用记录日志,则把LoggerOperation实现类中的end方法的打印注释掉后,

运行一下,你就会发现,每个方法之后没有记录日志了. 这样,我们就把代理者和操作者解藕啦!!!

 

附:下面留一个问题给大家,如果我们不想让所有方法都被日志记录,我们应该怎么去解藕呢?

想法是在代理对象的public Object invoke(Object proxy, Method method, Object[] args)方法里面加上个if(),

对传进来的method的名字进行判断,判断的条件存在XML里面.这样我们就可以配置文件时行解藕了.

如果有兴趣的朋友可以把操作者,被代理者,都通过配置文件进行配置 ,那么就可以写一个简单的SpringAOP框架了


LoggerOperation

你可能感兴趣的:(AOP代码实现理解(三))