本文由博主原创,转载请注明出处

完整源码下载地址 https://github.com/MatrixSeven/JavaAOP

上一篇,咱们说了使用Java原生代理实现AOP的简单例子,然么就不得不说一下Annotation这个东西了.注解(Annotation)是什么.吓得小柒君赶紧百度下:

  1. 注解基础知识点
  2. 定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

    作用分类:
  3. 编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】
  4. 代码分析:通过代码里标识的元数据对代码进行分析【使用反射】
  5. 编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】

and so on….如果你对注解(Annotation)还没有了解请左移百度百科:Annotation和Java 注解

啊,,是不是很眼熟,这个不就是经常看到的那个@Override神马的么…原来这个东西就叫做注解啊.

—–引至百度:我个人使用的理解,annotation是一种在类、类型、属性、参数、局部变量、方法、构造方法、包、annotation本身等上面的一个附属品(ElementType这个枚举中有阐述),他依赖于这些元素而存在,他本身并没有任何作用,annotation的作用是根据其附属在这些对象上,根据外部程序解析引起了他的作用,例如编译时的,其实编译阶段就在运行:java Compiler,他就会检查这些元素,例如:@SuppressWarnings、@Override、@Deprecated等等;



的确是,但是想想Spring的IOC依赖注入,控制反转@xxx(xxx=xxx)然后Bean里就被赋值了,是不是觉得好帅,哈,是不是也觉得好神奇?

是不是我创建一个注解,然后把他作用到类上就能赋值了?赶紧试一试…

首先,创建一个注解,用关键字@interface来声明,这是一个注解类.@Target来声明注解目标,

@Retention用来说明该注解类的生命周期.

  1. package proxy.annon;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. @Retention(RetentionPolicy.RUNTIME)
  7. @Target({ElementType.FIELD,ElementType.METHOD})
  8. public @interface Seven {
  9. public String value() default "小黑";
  10. public String Property() default "无属性";
  11. }

然后还用咱们昨天的写的JavaBean,加上注解后的样子就是:

  1. package proxy;
  2. import proxy.annon.Seven;
  3. import proxy.imp.AnimalInterface;
  4. public class DogImp implements AnimalInterface {
  5. @Seven(value = "Lumia")
  6. private String name;
  7. private String Property;
  8. public DogImp() {
  9. }
  10. @Override
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. @Override
  15. public String getName() {
  16. return this.name;
  17. }
  18. @Override
  19. public void say() {
  20. System.out.println("小狗:汪汪汪汪.....");
  21. }
  22. @Override
  23. @Seven(Property = "水陆两栖战士")
  24. public void setProperty(String Property) {
  25. this.Property = Property;
  26. }
  27. @Override
  28. public void getProperty() {
  29. System.out.println(this.name + this.Property);
  30. }
  31. }

迫不及待运行下:

  1. package proxy;
  2. public class Test {
  3. public static void main(String[] args) {
  4. DogImp dogImp = new DogImp();
  5. System.out.println(dogImp.getName());
  6. dogImp.getProperty();
  7. }
  8. }
  9. 输出:
  10. null
  11. nullnull

额.好伤心,表示并没有什么效果,那@的注入到底是怎么实现的呢….

转了一圈,还得依赖咱们的反射大军哈哈…..

赶紧改造下昨天的Demo,让其能够注解..咱们一起来…

注解已经创建好了,怎么让咱们的注解产生效果呢,赶紧动手写个AnnoInjection类.

用来实现注解的内容的注入..

但是要注意,让注如属性的时候,一定要有对用的get/set方法,如果访问级别为private则可以直接使用

属性的set(obj, value),如果为public,则需要自己获取方法,然后调用方法的invoke

  1. package proxy.annon;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. public class AnnoInjection {
  5. public static Object getBean(Object obj) {
  6. try {
  7. // 获得类属性
  8. Field f[] = obj.getClass().getDeclaredFields();
  9. // 遍历属性
  10. for (Field ff : f) {
  11. // 获得属性上的注解
  12. Seven s = ff.getAnnotation(Seven.class);
  13. if (s != null) {
  14. System.err.println("注入" + ff.getName() + "属性" + "tt" + s.value());
  15. // 反射调用public set方法,如果为访问级别private,那么可以直接使用属性的set(obj,
  16. // value);
  17. obj.getClass()
  18. .getMethod("set" + ff.getName().substring(0, 1).toUpperCase() + ff.getName().substring(1),
  19. new Class[] { String.class })
  20. .invoke(obj, s.value());
  21. }
  22. }
  23. // 获得所有方法
  24. Method m[] = obj.getClass().getDeclaredMethods();
  25. for (Method mm : m) {
  26. // 获得方法注解
  27. Seven s = mm.getAnnotation(Seven.class);
  28. if (s != null) {
  29. System.err.println("注入" + mm.getName() + "方法" + "t" + s.Property());
  30. mm.invoke(obj, s.Property());
  31. }
  32. }
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. }
  36. return obj;
  37. }
  38. }

这样呢,就实现了属性的方法的注入..在哪里调用呢…….

哦,,查看之前的AnimalFactory代码,会发现在getAnimalBase里有

  1. Proxy.newProxyInstance(obj.getClass().getClassLoader(),
  2. obj.getClass().getInterfaces(),
  3. new AOPHandle(obj,method))

很明显,咱们的动态代理new AOPHandle(obj,method)时传入了反射生成obj.然后实现代理拦截直接,

咱们来先处理这个obj.所以咱们简单修改下这个就好了

修改后的样子:

  1. /***
  2. * 获取对象方法
  3. * @param obj
  4. * @return
  5. */
  6. private static Object getAnimalBase(Object obj,AOPMethod method){
  7. //获取代理对象
  8. return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
  9. obj.getClass().getInterfaces(),
  10. new AOPHandle(AnnoInjection.getBean(obj),method));
  11. }

soga….看起来完美了,,赶紧跑起来试一试..

不对..之前的方法拦截太罗嗦,咱们只拦截getProperty方法..好吧

要不然输出太恶心了….

修改后的AOPTest….

  1. package proxy;
  2. import java.lang.reflect.Method;
  3. import org.junit.runner.RunWith;
  4. import org.junit.runners.BlockJUnit4ClassRunner;
  5. import proxy.imp.AOPMethod;
  6. import proxy.imp.AnimalInterface;
  7. @RunWith(BlockJUnit4ClassRunner.class)
  8. public class AOPTest {
  9. public static void main(String[] args) {
  10. AnimalInterface dog = AnimalFactory.getAnimal(DogImp.class, new AOPMethod() {
  11. // 这里写方法执行前的AOP切入方法
  12. public void before(Object proxy, Method method, Object[] args) {
  13. if (method.getName().equals("getProperty")) {
  14. System.err.println("成功拦截" + method.getName() + "方法,启动");
  15. }
  16. }
  17. // 这里系方法执行后的AOP切入方法
  18. public void after(Object proxy, Method method, Object[] args) {
  19. if (method.getName().equals("getProperty"))
  20. System.err.println("成功拦截" + method.getName() + "方法,结束");
  21. }
  22. });
  23. dog.say();
  24. String name1 = "我的名字是" + dog.getName();
  25. System.out.println(name1);
  26. dog.setName("二狗子");
  27. String name2 = "我的名字是" + dog.getName();
  28. System.out.println(name2);
  29. dog.getProperty();
  30. }
  31. }

然后给我run起来….

beauty,成功出来了呢..赶紧上个图,高兴下..

哈哈哈……大家是够有许多感悟呢,咱们下次再见

吾爱Java(QQ群):170936712

使用Java原生代理实现数据注入的更多相关文章

  1. 使用Java原生代理实现AOP

    ### 本文由博主柒.原创,转载请注明出处 ### 完整源码下载地址 [https://github.com/MatrixSeven/JavaAOP](https://github.com/Matri ...

  2. 23个适合Java开发者的大数据工具和框架

    转自:https://www.yidianzixun.com/article/0Ff4gqZQ?s=9&appid=yidian&ver=3.8.4&utk=6n9c2z37 ...

  3. [转]Java动态代理

    动态代理在Java中有着广泛的应用,比如Spring AOP,Hibernate数据查询.测试框架的后端mock.RPC,Java注解对象获取等.静态代理的代理关系在编译时就确定了,而动态代理的代理关 ...

  4. 《Java设计模式》之代理模式 -Java动态代理(InvocationHandler) -简单实现

    如题 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式可细分为如下, 本文不做多余解释 远程代理 虚拟代理 缓冲代理 保护代理 借鉴文章 ht ...

  5. Java动态代理——框架中的应用场景和基本原理

    前言 之前已经用了5篇文章完整解释了java动态代理的原理,本文将会为这个系列补上最后一块拼图,展示java动态代理的使用方式和应用场景 主要分为以下4个部分 1.为什么要使用java动态代理 2.如 ...

  6. Java 动态代理原理图解 (附:2种实现方式详细对比)

    ​ 动态代理在 Java 中有着广泛的应用,例如:Spring AOP 面向切面编程,Hibernate 数据查询.以及 RPC Dubbo 远程调用等,都有非常多的实际应用@mikechen 目录 ...

  7. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  8. Java动态代理全面分析

    代理模式 解说:给某一个对象提供一个代理,并由代理对象控制对原对象的引用: 代理模式需要以下几个角色: 1  主题:规定代理类和真实对象共同对外暴露的接口: 2  代理类:专门代理真实对象的类: 3 ...

  9. 学习AOP之JAVA的代理机制

    从一个输出日志的实例分析JAVA的代理机制 一.通用的日志输出方法  :需要在每个类里都增加对输出日志信息的代码 二.通过面向接口编程实现日志的输出(JAVA的静态代理):虽然实现了业务逻辑与输出日志 ...

随机推荐

  1. 无效的 URI: 未能分析证书颁发机构/主机

    出 现该错误的原因是URL中少了一个斜杠,正常的URL是“http:”后边有两个斜杠,而我在修改配置文件中的URL的IP地址部分时,不小心删掉了一个 斜杠,例如:http:/blog.csdn.net ...

  2. Unable to execute dex: Multiple dex files define异常的解决办法

    问题: [2016-01-06 16:47:58 - Dex Loader] Unable to execute dex: Multiple dex files define Landroid/sup ...

  3. poj 1753 Flip Game 枚举(bfs+状态压缩)

    题目:http://poj.org/problem?id=1753 因为粗心错了好多次……,尤其是把1<<15当成了65535: 参考博客:http://www.cnblogs.com/k ...

  4. poj 1259 Agri-Net(最小生成树)

    题目:http://poj.org/problem?id=1258 题意:模板题 和2485差不多 就是求相连后的最小值. #include <iostream> #include< ...

  5. MySQL timed_mutexes

    提要: MySQL 5.5.39 Release版本正式从源码里删除了全局参数timed_mutexes.timed_mutexes原本用来控制是否对Innodb引擎的mutex wait进行 计时统 ...

  6. poj2436,poj3659,poj2430

    这两题都体现了dp的核心:状态 dp做多就发现,状态一设计出来,后面的什么都迎刃而解了(当然需要优化的还要动动脑筋): 先说比较简单的: poj2436 由题得知病毒种数<=15很小,于是我们就 ...

  7. NOI2009植物大战僵尸

    这题应该分两步来做: 1.拓扑排序,去掉无敌点 2.求最大闭合子图 需要注意几点: 1.拓扑排序时,如果(i,j)可以攻击到(x,y),那么增加(x,y)的入度,而不是(i,j)的入度 因为入度代表着 ...

  8. 《C#并行编程高级教程》第9章 异步编程模型 笔记

    这个章节我个人感觉意义不大,使用现有的APM(异步编程模型)和EAP(基于时间的异步模型)就很够用了,针对WPF和WinForm其实还有一些专门用于UI更新的类. 但是出于完整性,还是将一下怎么使用. ...

  9. process thread Fiber(linux)

    http://blog.chinaunix.net/uid-21084809-id-2215376.html Processes, kernel threads, user threads, and ...

  10. [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.5.1

    Show that the inner product $$\bex \sef{x_1\wedge \cdots \wedge x_k,y_1\wedge \cdots\wedge y_k} \eex ...