Java通过JDK动态代理简单的实现一个AOP

首先说一下,因为自己还没有去研读spring的AOP的源码,只是大致知道其功能,便想着自己先手动实现一个先看看,觉得这样以后研读源码的时候会收获更多!

实现:做一个在添加注解的方法执行之前,可以先执行另一个方法。类似AOP(@Brfore),不明白的同学可以去百度下,这边只做一个简单的现实。

首先准备一个接口IEat,作为你要做的事情比如,eat():

public interface IEat {
    void eat();
}

然后两个类去实现这个接口,一个是我们的主要方法(原有不可变动的功能,这边自定义了一个@DoPre注解类似于@Before)Eat,一个是我们的代理类MyProxy,代理类还需去实现InvocationHandler这个接口,并且将cook()方法放在invoker()方法前(这个方法不清楚的同学可以去百度下,他在这里是实现执行Eat中的eat()方法,这样就相当于我前置了我需要添加的方法,吃之前得先做饭):

public class Eat implements IEat {
    @DoPre
    @Override
    public void eat() {
        System.out.println("eateateat");
    }
}
public class MyProxy implements InvocationHandler, IEat {
    private Object object;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        cook();
        method.invoke(object);
        return null;
    }

    public MyProxy(Object object) {
        this.object = object;
    }

    @Override
    public void eat() {
    }

    private void cook() {
        System.out.println("cooking");
    }
}

@DoPre注解没有具体做啥,只是作为一个标记,记得加@Retention(RetentionPolicy.RUNTIME)是指运行时能通过反射找到注解:

@Retention(RetentionPolicy.RUNTIME)
public @interface DoPre {}

最后main方法作为启动器,初始化init()方法负责扫面当前包下的带有这个@DoPre注解的方法,这边的初始化写的很简单,没有去遍历其他的包和子包,一切求简,可以自己优化很多地方:

public class Test {
    public static IEat eat;

    //start
    public static void main(String[] args) {
        init();
        eat.eat();
    }

    private static void init() {
        Class clazz = Test.class;
        String packagePath = clazz.getResource("").getPath();
        String packagename = clazz.getPackage().getName();
        File file = new File(packagePath);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            assert files != null;
            for (File file1 : files) {
                try {
                    StringBuilder stringBuilder = new StringBuilder(packagename);
                    stringBuilder.append(".").append(file1.getName());
                    String s = stringBuilder.toString().replace(".class", "");
                    Class clazz1 = Class.forName(s);
                    Method[] methods = clazz1.getMethods();
                    for (Method method : methods) {
                        Annotation[] annotations = method.getDeclaredAnnotations();
                        for (Annotation annotation : annotations) {                 //找到注解方法
                            if (annotation.toString().contains("DoPre")) {                   //传入被代理的实例clazz1.newInstance()
                                IEat proxy = (IEat) Proxy.newProxyInstance(Test.class.getClassLoader(), MyProxy.class.getInterfaces(), new MyProxy(clazz1.newInstance()));                   //注入对象
                                eat = proxy;
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

自己本身也是个新人,所以望大佬们见谅,代码并没有写得完美,更像是演示一这个功能,但是核心思想应该是差不多的,而且越简单可以让同学理解更快,我们学习的更应该是思想!

原文地址:https://www.cnblogs.com/junalncer/p/11663113.html

时间: 2024-10-23 04:55:33

Java通过JDK动态代理简单的实现一个AOP的相关文章

设计模式之动态代理(Java的JDK动态代理实现)

对于JDK的动态代理,孔浩老师说学习的方法是把它记下来. 先写一个主题接口类,表示要完成的一个主题. package com.liwei.dynaproxy; /** * 要代理的主题接口 * @author Administrator * */ public interface Subject { public void miai(); } 再写一个实现类,这个实现类实现这个接口.当然,这个实现类就是我们要代理的对象. 为了区别不同的类的对象,我们为Person类增加了一个name属性,并且通

Spring AOP基础之JDK动态代理

JDK动态代理 Jdk动态代理是装饰模式的一个典型用例,关于装饰模式这里不多解释,直接说重点吧.jdk动态代理实际上就是代替继承方案,在不破坏原始类的原则下,在运行期间为某个类动态注入一些新的方法.java.lang.reflect.Proxy提供了生成代理类的接口.进入源代码,我们可以看见关于Proxy的详细说明这里截取一些关键的部分: /** * {@code Proxy} provides static methods for creating dynamic proxy * classe

jdk动态代理底层实现

一.代理设计模式 代理设计模式是Java常用的设计模式之一. 特点: 01.委托类和代理类有共同的接口或者父类: 02.代理类负责为委托类处理消息,并将消息转发给委托类: 03.委托类和代理类对象通常存在关联关系,一个代理类对象与一个委托类对象关联: 04.代理类本身不是真正的实现者,而是通过调用委托类方法来实现代理功能: 二.静态代理与动态代理 按照代理类创建的时机,代理类分为两种: 01.静态代理:由我们程序猿或者特定的工具自动生成了源代码,在程序运行之前,class文件已经存在了:例如在s

Cglib和jdk动态代理的区别

动态代理解决了方法之间的紧耦合, IOC解决了类与类之间的紧耦合! Cglib和jdk动态代理的区别? 1.Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理 2. Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理 什么时候用cglib什么时候用jdk动态代理? 1.目标对象生成了接口 默认用JDK动态代理 2.如果目标对象使

JDK动态代理连接池

JDK动态代理 ? 1 什么是JDK动态代理 刚刚写ItcastConnection时爽么?因为Connection中的方法太多了,每个都要写,所以很累吧.累点到是没什么,可以完成功能就是好的.但是不是什么时候可以用代理的,有时你可能会遇到要代理的东西,只有在运行时才能知道,所以你不可能先把代理写出来!这时就需要使用动态代理. JDK动态代理是JavaSE中一个高级特性,不是那么好理解的,但是它可是框架们的"秘密武器".你要是可以理解它,那么将来在学习框架时,你就会知道框架是怎么完成一

Java反射—运用反射生成jdk动态代理

1.  核心类&接口 在Java的java.lang.reflect包下提供一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口可以生成jdk动态代理类或动态代理对象. Proxy是所有动态代理类的父类,它提供了两个静态方法来创建动态代理类和动态代理对象,如下: ?  static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) ?  static Objec

Java学习之:JDK动态代理与CGLIB动态代理

代理的概念:简单的理解就是通过为某一个对象创建一个代理对象,我们不直接引用原本的对象,而是由创建的代理对象来控制对原对象的引用. 动态代理:是指在程序运行时由Java反射机制动态生成,无需手动编写代码.动态代理不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类. 代理原理:代理对象内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象.同时,代理对象可以在执行真实对象操作时,附加其他的操作

Java之美[从菜鸟到高手演练]之JDK动态代理的实现及原理

JDK动态代理的实现及原理 作者:二青 邮箱:[email protected]     微博:http://weibo.com/xtfggef 动态代理,听上去很高大上的技术,在Java里应用广泛,尤其是在Hibernate和Spring这两种框架里,在AOP,权限控制,事务管理等方面都有动态代理的实现.JDK本身有实现动态代理技术,但是略有限制,即被代理的类必须实现某个接口,否则无法使用JDK自带的动态代理,因此,如果不满足条件,就只能使用另一种更加灵活,功能更加强大的动态代理技术-- CG

java 静态代理 JDK动态代理 Cglib动态代理

下面以一个简单的银行账户为例讲述讲述动态代理. 设计一个银行账户类,包含用户的账户余额,实现查询和更新余额功能 这个系统用了一段时间,有客户要求对账说账户余额给弄错了?因为上面没有存取款记录,最后银行不认账,客户收到了损失.银行为了避免这种现象再次发生,决定对这个系统进行修改,但是因为bankAccount太过复杂,希望在不修改bankAccount的情况下,增加日志功能. 静态代理 使用静态代理解决上面的问题. 银行要求所有模块都需要添加日志功能,这对苦逼的程序员来说真的是一个不小的工作量啊,