自定义注解@Bean和@Resource 实现SpringIOC

Posted yzy4646

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义注解@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那样完成注入。




以上是关于自定义注解@Bean和@Resource 实现SpringIOC的主要内容,如果未能解决你的问题,请参考以下文章

java注解@Resource机制怎么取到注入过的Bean

SpringIOC的bean自动注解(Resource,Autowired)

SpringIOC的bean自动注解(Resource,Autowired)

SpringIOC的bean自动注解(Resource,Autowired)

Spring---ioc自动装配和使用注解

Spring 注解之@Autowired、@Qualifer以及@Resource的区别