1.定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExtService {
}
2.工具类
https://blog.csdn.net/qq_41988225/article/details/84393804
3.主要功能类
package com.wangyu.extspring.annotation;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang.StringUtils;
/**
* 手写ioc注解版本
*
*/
public class ExtClassPathXmlApplicationContext {
//扫包范围
private String packageName;
//存储加了注解的类
private static ConcurrentHashMap<String, Object> beansMap = null;
public ExtClassPathXmlApplicationContext(String packageName) throws Exception {
beansMap = new ConcurrentHashMap<String, Object>();
if (StringUtils.isEmpty(packageName)) {
return;
}
this.packageName = packageName;
initBeans();
initEntryField();
}
//给容器中的对象的初始化属性
public void initEntryField() throws Exception {
//遍历所有的bean容器对象,判断是否加了extresource注解
for (Entry<String, Object> entry : beansMap.entrySet()) {
String key = entry.getKey();
Object object = entry.getValue();
attrAssion(object);
}
}
//获取bean
public Object getBean(String beanId) throws Exception {
if (StringUtils.isEmpty(beanId)) {
throw new Exception("该beanid是空的");
}
//从spring容器获取bean
Object object = beansMap.get(beanId);
/**if (object == null) {
throw new Exception("class not found ");
}*/
//3.使用反射机制进行初始化
return object;
}
//初始化对象
public void initBeans() throws Exception {
//1.使用java反射机制,获取当前包下的所有类
List<Class<?>> classes = ClassUtil.getClasses(packageName);
//2.判断类上面是否有注解
ConcurrentHashMap<String, Object> classExisAnnotation = findClassExisAnnotation(classes);
if (classExisAnnotation == null) {
throw new Exception("该包的类没有加注解");
}
}
public ConcurrentHashMap<String, Object> findClassExisAnnotation(List<Class<?>> classes) throws ClassNotFoundException, InstantiationException,
IllegalAccessException {
for (Class<?> classInfo : classes) {
ExtService annotation = classInfo.getAnnotation(ExtService.class);
if (annotation != null) {
//类名小写作为beanId
String className = classInfo.getSimpleName();
String beanId = toLowerCaseFirstOne(className);
Object newInatance = newInatance(classInfo);
beansMap.put(beanId, newInatance);
continue;
}
}
return beansMap;
}
// 首字母转小写
public static String toLowerCaseFirstOne(String s) {
if (Character.isLowerCase(s.charAt(0)))
return s;
else
return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
}
//创建对象
public Object newInatance(Class<?> classInfo) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
return classInfo.newInstance();
}
//依赖注入原理分析
public void attrAssion(Object object) throws Exception {
Class<? extends Object> classInfo = object.getClass();
//获取属性
Field[] declaredFields = ((Class<?>) classInfo).getDeclaredFields();
for (Field field : declaredFields) {
ExtResource annotation = field.getAnnotation(ExtResource.class);
if (annotation != null) {
//获取属性名称
String beanId = field.getName();
Object bean = getBean(beanId);
if (bean != null) {
//默认使用属性名称,查找容器对象(当前对象,给属性赋值 )
field.setAccessible(true);
//给容器中的对象的属性进行赋值
field.set(object, bean);
}
}
}
}
}
4.测试
public class ExtTest {
public static void main(String[] args) throws Exception {
ExtClassPathXmlApplicationContext ext =
new ExtClassPathXmlApplicationContext("com.wangyu.extspring.annotation.service");
UserService bean = (UserService) ext.getBean("userService5");
System.out.println(bean);
}
}