Spring容器解析与简单demo
git上项目路径: https://github.com/0ziyu0/handWriting
实现原理:本文采用2个全局的ConcurrentHashMap集合来实现beansAlias集合存放所有带自定义注解的类其中key:类名首字母小写,value:注解中value属性,没有则首字母小写。
containerBeans集合存放所有自定义注解的类来实现。
步骤: 1.扫描指定路径下的所有class文件。
2.对其上有自定义注解的class放入一个全局的Map集合中,同时用一个容器来存放beanId(默认是类名首字母小写)[也可以更具类的类型来注入]。
3.遍历所有Map集合对其class中属性上有自定义注解进行赋值(依赖注入)。
1 public class ClassPathApplicationContextCustomer { 2 3 // 扫描包路径 4 private String scanPackagePath = null; 5 // 将所有自定义注解的class交给此类管理 6 private ConcurrentHashMap<String, Object> containerBeans = new ConcurrentHashMap<String, Object>(); 7 // 存放注解中bean的别名 8 private ConcurrentHashMap<String, String> beansAlias = new ConcurrentHashMap<String, String>(); 9 10 public ClassPathApplicationContextCustomer(String scanPackagePath) { 11 this.scanPackagePath = scanPackagePath; 12 List<Class> annotationClassList = getAllAnnotationClass(); 13 initAnnotationBean(annotationClassList); 14 for (Object classInfo : containerBeans.values()) { 15 attributeInjection(classInfo); 16 } 17 beansAlias = null; 18 } 19 20 // 得到包路径下所有的注解类 21 private List<Class> getAllAnnotationClass() { 22 23 List<Class> resultAllAnnotationClass = null; 24 if(StringUtil.isNotEmpty(scanPackagePath)) { 25 resultAllAnnotationClass = new ArrayList<Class>(); 26 String beanId = null; 27 String className = null; 28 // 获取包下所有类 29 List<Class<?>> classeList = ClassUtil.getClasses(scanPackagePath); 30 for (Class<?> classInfo : classeList) { 31 CustomerService customerServiceAnnotation = classInfo.getDeclaredAnnotation(CustomerService.class); 32 if(customerServiceAnnotation != null) { 33 resultAllAnnotationClass.add(classInfo); 34 // 是否有自定义bean的名字,没有则采用类名小写 35 beanId = customerServiceAnnotation.value(); 36 // 防止类重名,最好不用SimpleName()方法,这里简单处理 37 className = classInfo.getSimpleName(); 38 if(StringUtil.isEmpty(beanId)) { 39 beanId = StringUtil.toLowerCaseFirstOne(className); 40 } 41 beansAlias.put(className, beanId); 42 } 43 } 44 } 45 46 return resultAllAnnotationClass; 47 } 48 49 // 初始化bean容器[此方法也可以合并到getAllAnnotationClass()方法中] 50 private void initAnnotationBean(List<Class> AnnotationClassList) { 51 52 try { 53 Object instance = null; 54 String className = null; 55 for (Class classInfo : AnnotationClassList) { 56 instance = classInfo.newInstance(); 57 className = classInfo.getSimpleName(); 58 String beanId = beansAlias.get(className); 59 containerBeans.put(beanId, instance); 60 } 61 } catch (Exception e) { 62 e.printStackTrace(); 63 throw new RuntimeException(e); 64 } 65 66 } 67 68 // 属性的依赖注入 69 private void attributeInjection(Object object) { 70 71 try { 72 Class<? extends Object> classInfo = object.getClass(); 73 Field[] fieldArray = classInfo.getDeclaredFields(); 74 CustomerService customerServiceAnnotation = null; 75 String filedName = null; 76 Object injectionClass = null; 77 for (Field field : fieldArray) { 78 customerServiceAnnotation = field.getDeclaredAnnotation(CustomerService.class); 79 if(customerServiceAnnotation != null) { 80 filedName = field.getName(); 81 injectionClass = containerBeans.get(filedName); 82 if(injectionClass != null) { 83 field.setAccessible(true); 84 field.set(object, injectionClass); 85 } 86 } 87 } 88 } catch (Exception e) { 89 e.printStackTrace(); 90 throw new RuntimeException(e); 91 } 92 } 93 94 public Object getInstanceBean(String beanId) { 95 96 Object resultObject = null; 97 if(StringUtil.isNotEmpty(beanId)) { 98 resultObject = containerBeans.get(beanId); 99 } 100 101 return resultObject; 102 103 } 104 }
@Documented
@Target({ElementType.TYPE, ElementType.FIELD})
@Inherited
@Retention(RetentionPolicy.RUNTIME )
public @interface CustomerService {
String value() default "";
// String name() default "";
}
测试代码

dao
1 package com.hand.customer.spring.dao; 2 3 public interface CustomerApplicationContextDao { 4 5 public void testCustomerApplicationContextTest(); 6 7 }
dao.impl
1 package com.hand.customer.spring.dao.impl; 2 3 import com.hand.customer.spring.annotation.CustomerService; 4 import com.hand.customer.spring.dao.CustomerApplicationContextDao; 5 6 @CustomerService("customerDao") 7 public class CustomerApplicationContextDaoImpl implements CustomerApplicationContextDao { 8 9 public void testCustomerApplicationContextTest() { 10 11 System.out.println("this is test customer application content test dao impl..."); 12 13 } 14 15 }
service
1 package com.hand.customer.spring.service; 2 3 public interface CustomerApplicationContextService { 4 5 public void testCustomerApplicationContextTest(); 6 7 }
service.impl
1 package com.hand.customer.spring.service.impl; 2 3 import com.hand.customer.spring.annotation.CustomerService; 4 import com.hand.customer.spring.dao.CustomerApplicationContextDao; 5 import com.hand.customer.spring.service.CustomerApplicationContextService; 6 7 @CustomerService() 8 public class CustomerApplicationContextServiceImpl implements CustomerApplicationContextService { 9 10 @CustomerService("customerDao") 11 private CustomerApplicationContextDao customerDao; 12 13 public void testCustomerApplicationContextTest() { 14 15 System.out.println("============== 注解版本(根据bean首字母小写注入) =================="); 16 customerDao.testCustomerApplicationContextTest(); 17 } 18 19 }
Test方法
1 package com.hand.customer.spring; 2 3 import com.hand.customer.spring.service.CustomerApplicationContextService; 4 5 public class ClassPathApplicationContextCustomerTest { 6 7 public static void main(String[] args) { 8 9 ClassPathApplicationContextCustomer app = new ClassPathApplicationContextCustomer("com.hand.customer.spring"); 10 CustomerApplicationContextService customerService = (CustomerApplicationContextService) app.getInstanceBean("customerApplicationContextServiceImpl"); 11 customerService.testCustomerApplicationContextTest(); 12 } 13 14 }
运行测试


浙公网安备 33010602011771号