在实际项目开发中,基本已经离不开spring框架了,而spring框架的成功之处在于起IOC以及AOP强大的解耦功能。今天给大家带来自己所简单实现的一个IOC注入。
编写@Bean以及@Resource 注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Bean { String value(); }
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Resource { String value(); }
@Target标识此注解只能在类上使用
@Retention标识直到运行时态依旧能找到此注解
编写AnnotationUtil 方法类其中定义map做为springBean的容器,读取项目所有的类将类上标有@Bean注解的类放入到容器,以及resource注解注入方法
package com.skyyun.util; import java.io.File; import java.lang.reflect.Field; import java.util.HashMap; import com.skyyun.annotation.Bean; import com.skyyun.annotation.Resource; public class AnnotationUtil { /** * bean容器 */ private static java.util.Map<String, Object> Map; static{ try { getAllBeansToMap(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * resource注解注入 * @param object */ public static void annotationIOC(Object object){ Class clazz=object.getClass(); //获取类的所有包括私有的属性 Field[] Fields = clazz.getDeclaredFields(); for (Field field : Fields) { Resource annotation = field.getAnnotation(Resource.class); if(annotation!=null){ //允许改变私有属性 field.setAccessible(true); String value = annotation.value(); try { field.set(object, Map.get(value)); } catch (Exception e) { e.printStackTrace(); } } } } /** * 获取此工程所有的bean存储到容器中 * @throws Exception */ private static void getAllBeansToMap() throws Exception { Map = new HashMap<>(); getClassName(); } /** * 获取此项目中所有的java全路径名, * @throws Exception */ private static void getClassName() throws Exception { // 获取到此项目的src路径 String path = System.getProperty("user.dir") + "\\src"; File files = new File(path); getClassFileName(files, ""); } /** * 获取所有类的全路径名,并把类初始化入容器 * * @param path * @param directoryName * @throws Exception */ private static void getClassFileName(File files, String directoryName) throws Exception { if (files != null) { if (directoryName == null) { directoryName = ""; } String name = null; File[] listFiles = files.listFiles(); if (listFiles != null) { for (int i = 0; i < listFiles.length; i++) { if (listFiles[i].isDirectory()) { // 为目录 name = listFiles[i].getName(); File files2 = new File(files.getPath() + "\\" + name); if(directoryName.equals("")){ getClassFileName(files2, directoryName + name); }else{ getClassFileName(files2, directoryName + "." + name); } // System.out.println(name); } else { // 不为目录 name = listFiles[i].getName(); name = name.substring(0, name.lastIndexOf(".")); if(directoryName.equals("")){ setMap(directoryName + name); }else{ setMap(directoryName + "." + name); } } } } } } /** * 将带有@Bean初始化到容器 * @param name * @throws Exception */ private static void setMap(String name) throws Exception{ Class clazz=Class.forName(name); //查找此类上是否有此注解 Bean bean = (Bean) clazz.getAnnotation(Bean.class); if(bean!=null){ Map.put(bean.value(),clazz.newInstance()); } } }
编写测试类,以及测试方法
package com.skyyun.dao; import com.skyyun.annotation.Bean; @Bean("userDao") public class UserDao { public void inserUser(){ System.out.println("添加用户"); } public void updateUser(){ System.out.println("更改用户"); } public void deleteUser(){ System.out.println("删除用户"); } public void selectUser(){ System.out.println("查询用户"); } }
package com.skyyun.service; import com.skyyun.annotation.Resource; import com.skyyun.dao.UserDao; import com.skyyun.util.AnnotationUtil; public class UserService { public UserService() { super(); //调用IOC方法注入 AnnotationUtil.annotationIOC(this); } @Resource("userDao") private UserDao userDao; public void inserUser(){ userDao.inserUser(); } public void updateUser(){ userDao.updateUser(); } public void deleteUser(){ userDao.deleteUser(); } public void selectUser(){ userDao.selectUser(); } }
编写测试类
package com.skyyun.test; import com.skyyun.service.UserService; public class Test { public static void main(String[] args) throws Exception { UserService service = new UserService(); service.deleteUser(); service.inserUser(); service.updateUser(); service.selectUser(); } }
运行此类最后得到结果
删除用户
添加用户
更改用户
查询用户
总结
此法使用io流读取当前项目所有的java文件,利用java自身的反射以及注解的方式实现springIOC,此方法还有很多不完善的地方,比如@Resource注入是在类的构造方法调用方法注入,并不能像spring那样完成注入。