Java注解的使用,实现仿Spring的对象装载
来源:互联网 发布:淘宝虚拟网店取消 编辑:程序博客网 时间:2024/06/05 03:02
Java注解的使用,实现仿Spring的对象装载
看到Spring的注解,相信大家和我一样,都很想知道它怎么工作的,它是怎么实现注入的功能吧。废话就不用多说了,我们直接开始进入正题吧。
实现仿Spring的注解,只需要四步。
1.注解的创建
注解的创建很简单,只需要知道其基本语法就行了。
@interface 用来创建注解
@Retention 用来声明注解生命周期
@Target 用来声明注解适用范围
@Inherited 用来描述注解可引用至注解的类的子类(本文未用到)
@Document 用来指示注解将被文档化。
具体的值可以参考JavaAPI
1.1 创建用于声明bean对象的注解Component.java
package com.test.annotation.test3.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE})//声明该注解用于类、接口等定义时期public @interface Component { String value() default "";}
1.2 创建依赖注入的注解Bean.java
package com.test.annotation.test3.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)//声明该注解生命周期为运行时,即要被虚拟机识别@Target(ElementType.FIELD)//声明该注解用于字段定义时期public @interface Bean { String value() default "";}
1.3 创建用于注入值的注解Value.java:
package com.test.annotation.test3.annotation;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface Value { String value() default "";}
上文提到两个类RetentionPolicy和ElementType,它们分别是帮助注解描述生命周期和作用范围,想要详细了解,请参考JavaAPI
2.业务逻辑的实现
2.1 创建模型层Model.java
package com.test.annotation.test3.content;import com.test.annotation.test3.annotation.Component;import com.test.annotation.test3.annotation.Value;@Component("model")public class Model { @Value("张三") public String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}
2.2 创建Dao层Dao.java:
package com.test.annotation.test3.content;import com.test.annotation.test3.annotation.Bean;import com.test.annotation.test3.annotation.Component;@Component("dao")public class Dao { @Bean("model") public Model model; @Override public String toString() { String text="name:"+model.getName(); return text; }}
2.3 创建service层Service.java:
package com.test.annotation.test3.content;import com.test.annotation.test3.annotation.Bean;import com.test.annotation.test3.annotation.Component;@Component("service")public class Service { @Bean("dao") public Dao dao; @Override public String toString() { return dao.toString(); }}
3.创建对象的注入工具(关键):
package com.test.annotation.test3.content;import java.io.File;import java.lang.reflect.Field;import java.util.HashMap;import java.util.Map;import com.test.annotation.test3.annotation.Bean;import com.test.annotation.test3.annotation.Component;import com.test.annotation.test3.annotation.Value;public class AnnotationUtil { public Map<String, Object> maps = new HashMap<String, Object>(); /** * 初始化注解 * @param packageName 搜索包路径名 * @throws Exception */ public void initAnnotation(String packageName) throws Exception { packageName += "."; byte[] packagePathForByte = packageName.getBytes(); //把包路径转化为文件路径 for (int i = 0; i < packagePathForByte.length; i++) { if (packagePathForByte[i] == '.') { packagePathForByte[i] = File.separator.getBytes()[0]; } } String packagePath = new String(packagePathForByte); //这里限制了搜索的路径的位置是基于源码的src目录下的类路径开始,需要根据实际需要更改 File root = new File(System.getProperty("user.dir") + File.separator + "src" + File.separator + packagePath + File.separator); loopClazz(root, packageName); for (String key : maps.keySet()) { Object object=maps.get(key); inject(object); } } /** * 循环遍历文件夹下的类 * @param folder 搜索的类的路径 * @param packageName 包名(用于创建对象) * @throws Exception */ private void loopClazz(File folder, String packageName) throws Exception { File[] files = folder.listFiles(); for (int fileIndex = 0; fileIndex < files.length; fileIndex++) { File file = files[fileIndex]; if (file.isDirectory()) { loopClazz(file, packageName + file.getName() + "."); } else { initClazz(file.getName(), packageName); } } } /** * 实现对注解的类的初始化 * @param filename java类的名称 * @param packageName 包的名称 */ private void initClazz(String filename, String packageName) { try { //用于除去".java"的后缀 String name = filename.substring(0, filename.length() - 5); Object obj=Class.forName(packageName + name).newInstance();//通过类名加载对象,并创建对象是实例 Class clazz = obj.getClass(); //判断类是否被Component注解 if (clazz.isAnnotationPresent(Component.class)) { Component component = (Component) clazz.getAnnotation(Component.class);//获取到Component注解 maps.put(component.value(), obj); } } catch (Exception e) { System.out.println("exception = " + e.getLocalizedMessage()); } } /** * 对对象进行装配 * @param object 装配的目标 */ public <T> void inject(T object) { try { Class clazz = object.getClass(); Field[] fields = clazz.getDeclaredFields();//获取参数列表 for (Field field : fields) { //如果是Bean注解,就获取map中的对象,装配到目标对象中 if (field.isAnnotationPresent(Bean.class)) { Bean bean = field.getAnnotation(Bean.class); field.set(object, maps.get(bean.value())); } //如果是Value注解,就获取注解的值,装配到目标对象中 else if (field.isAnnotationPresent(Value.class)) { Value value = field.getAnnotation(Value.class); field.set(object, value.value()); } } } catch (Exception e) { System.out.println("exception = " + e.getLocalizedMessage()); } }}
4.测试代码的实现:
package com.test.annotation.test3.content;public class Action { public static void main(String[] args) { Service service=new Service(); try { AnnotationUtil util=new AnnotationUtil(); util.initAnnotation("com.test.annotation.test3.content");//初始化注解程序,类似Spring的包搜索 util.inject(service);//装载对象 System.out.println(service.toString()); } catch (Exception e) { e.printStackTrace(); } }}
以上只是简单的实现了注入功能,设计比较简单,主要用于学习注解,如果有什么意见或者建议,欢迎探讨,如果有什么疑问急需要解决,可以发送邮件至我的邮箱1129115956@qq.com。
0 0
- Java注解的使用,实现仿Spring的对象装载
- Java 普通类实现spring bean的自定装载
- Spring-基于注解的配置[02自动装载bean]
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- Spring使用注解的方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- 使用Spring的注解方式实现AOP
- MFC鼠标动态位置提示框
- win10+TPLINK,用PXE安装redhat系统
- spring jar包的介绍
- 4.IPC 机制(二) IPC基础概念介绍
- mysql给新用授予权限Can't find any matching row in the user table
- Java注解的使用,实现仿Spring的对象装载
- JavaScript也能写爬虫-新浪微博【按关键字】采集爬虫
- TextView显示单行文本多余...显示
- jsp 取得DataGrid数据的代码实例(有checkBoxs 的DataGrid)
- orcle序列的创建删除
- Notepad++的列编辑功能
- test 11-10 [水题 状压DP dfs序+线段树]
- RotateAnimation 动画的参数详解
- android 下c++创建文件摘要