zoukankan      html  css  js  c++  java
  • 自定义注解@Bean和@Resource 实现SpringIOC

      在实际项目开发中,基本已经离不开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那样完成注入。

  • 相关阅读:
    送给有缘的人,2007年9月20日可买入股票
    上次9.19推荐的兰太实业停牌的公告,有持有的朋友可查看
    送给有缘的人,2007年9月24日可买入股票
    对古越龙山的惆怅
    将PDA矢量图控件开源
    读取PE文件的导入表
    [非原创] 用于将真彩色图像降级为索引图像的八叉树算法
    读取PE文件的资源表
    [VC6] 图像文件格式数据查看器
    关于 AlphaBlend 和 32bpp 的反锯齿图标
  • 原文地址:https://www.cnblogs.com/yzy4646/p/8410372.html
Copyright © 2011-2022 走看看