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

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

最新文章

  1. (第七天)DOM练习一
  2. Dorado7 4版本升级5版本问题汇总
  3. 《OD学Oozie》20160807Oozie
  4. 想让安卓 APP 如丝般顺滑?
  5. 我是如何理解Java抽象类和接口的
  6. AndroidStudio运行java的main方法
  7. bash 和sed 和gawk
  8. MVC+EF 序列化类型为“System.Data.Entity.DynamicProxies.__的对象时检测到循环引用
  9. LINK:fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 (转)
  10. 2018.10.27 bzoj3209: 花神的数论题(数位dp)
  11. linux下c语言实现双进程运行
  12. <<APUE>> 编译方法
  13. python使用venv环境报Python.h : No such file or direc
  14. 阿里云VPS(win系统)装ROS教程
  15. jquery实现漂亮的轮播图
  16. 20172330 2017-2018-1 《Java程序设计》第五周学习总结
  17. [python]字符串的ljust方法
  18. SQL server T-sql语句查询执行顺序
  19. JetBrains PyCharm 2017.3注册码
  20. Django 路由、模板和模型系统

热门文章

  1. ACM-ICPC 2017 Asia Urumqi:A. Coins(DP) 组合数学
  2. NOIP 2009 最优贸易 题解
  3. Java服务器-Disruptor使用注意
  4. Python---环境以及编辑器的使用的学习
  5. 详细的漏洞复现:Shellshock CVE-2014-6271 CVE-2014-7169
  6. javascript合并两个数组
  7. 实战spring自定义属性(schema)
  8. C++11新增容器以及元组
  9. 〈三〉ElasticSearch的认识:搜索、过滤、排序
  10. MOOC 数据库系统笔记(一):初步认识数据库系统