首先说一下,因为自己还没有去研读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();
}
}
} } }

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

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

  1. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

  2. [编织消息框架][JAVA核心技术]jdk动态代理

    需要用到的工具  jdk : javac javap class 反编译 :JD-GUI http://jd.benow.ca/ import java.lang.reflect.Invocation ...

  3. JDK动态代理简单小程序

    Jdk动态代理 1.动态代理使用的情况:需要在多个方法上加上相同的逻辑的时候,需要用到动态代理. 原因:在多个方法上写相同的逻辑,第一费事,第二在不用的时候维护麻烦 使用动态代理需要用到两个类:分别为 ...

  4. java之JDK动态代理

    © 版权声明:本文为博主原创文章,转载请注明出处 JDK动态代理: JDK动态代理就是在程序运行期间,根据java的反射机制自动的帮我们生成相应的代理类 优势: - 1. 业务类只需要关注业务逻辑本身 ...

  5. aop学习总结一------使用jdk动态代理简单实现aop功能

    aop学习总结一------使用jdk动态代理实现aop功能 动态代理:不需要为目标对象编写静态代理类,通过第三方或jdk框架动态生成代理对象的字节码 Jdk动态代理(proxy):目标对象必须实现接 ...

  6. Java基础-jdk动态代理与cglib动态代理区别

    JDK动态代理 此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑. 代理模式在实际使用时需要指定具体的目标对象 ...

  7. JDK动态代理简单使用(2)

    JDK动态代理使用: 使用JDK动态代理步骤: ①创建被代理的接口和类: public interface IA { void f1(String param); } public class A i ...

  8. Java基础-JDK动态代理

    JDK的动态代理依靠接口实现  代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...

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

    先来看一下思维导图: 对于JDK的动态代理,孔浩老师说学习的方法是把它记下来. 先写一个主题接口类,表示要完成的一个主题. package com.liwei.dynaproxy; /** * 要代理 ...

随机推荐

  1. hdu 5902 GCD is Funny

    Problem Description Alex has invented a new game for fun. There are n integers at a board and he per ...

  2. 【Redis】SpringBoot+Redis+Ehcache实现二级缓存

    一.概述 1.1 一些疑惑? 1.2 场景 1.3 一级缓存.两级缓存的产生 1.4 流程分析 二.项目搭建 一.概述 1.1 一些疑惑? Ehcache本地内存 Redis 分布式缓存可以共享 一级 ...

  3. 相同类中方法间调用时日志Aop失效处理

    本篇分享的内容是在相同类中方法间调用时Aop失效处理方案,该问题我看有很多文章描述了,不过大多是从事务角度分享的,本篇打算从日志aop方面分享(当然都是aop,失效和处理方案都是一样),以下都是基于s ...

  4. 实验吧CTF练习题---WEB---FALSE解析

    实验吧web之FALSE 地址:http://www.shiyanbar.com/ctf/1787 flag值:CTF{t3st_th3_Sha1}   解题步骤: 1.点开题目链接,观察题意 2.题 ...

  5. Corosync fence盘替换

    前面创建盘的步骤省略 1.在节点A执行: sbd -d /dev/mapper/fence_lun001 -d /dev/mapper/fence_lun002 -d /dev/mapper/fenc ...

  6. NGUI_基础入门学习

    目录 1. Control Widgets 控制部件2. Anchors 锚3. Interaction 交互4. Menu 菜单5. Controller Input 控制器的输入6. Lights ...

  7. Kubernetes监控实践

    一.Kubernetes介绍 Kubernetes(K8s)是一个开源平台,能够有效简化应用管理.应用部署和应用扩展环节的手动操作流程,让用户更加灵活地部署管理云端应用. 作为可扩展的容错平台,K8s ...

  8. 解决mysql不能在查询A表的同时,更新A表的问题

    方法: 运用中间表 UPDATE 表名 SET 字段名 = '' WHERE id in (SELECT a.id FROM (SELECT id FROM 表名 WHERE ISNULL(字段名)) ...

  9. java中的逃逸分析

    逃逸分析 public static StringBuffer craeteStringBuffer(String s1, String s2) { StringBuffer sb = new Str ...

  10. 搭建第一个node服务器

    1.在项目文件夹根目录创建app.js: (1)先引入模块 const http = require('http');//http是安装好node就有的一个模块,是用来创建http服务器的 (2)创建 ...