Spring之手写一个依赖注入容器  1. 创建两个自定义注解   2. ApplicationContext接口与实现类 2.1 ApplicationContext 接口 2.2 实现类:DefaultListableApplicationContext 3. 定义DAO层和Service层及其实现 4. 定义异常信息类 4.1 InjectBeanException 4.2 NotExistsBean 4.3 NotSupportMoreSuperInterface 5. 测试自定义bean容器(带依赖注入) 5.1 新建测试类TestUser 5.2 输出结果   
 
@Target ( value =  ElementType . TYPE ) 
@Retention ( RetentionPolicy . RUNTIME ) 
public  @interface  Component  { String  value ( )  default  "" ; 
} 
@Target ( value =  ElementType . FIELD ) 
@Retention ( RetentionPolicy . RUNTIME ) 
public  @interface  DI  { String  value ( )  default  "" ; } 
public  interface  ApplicationContext  { Object  getBean ( String  name) ; < T > T  getBean ( String  name,  Class < T > ) ; boolean  exists ( String  name) ; boolean  exists ( String  name,  Class < ? > ) ; 
} 
public  class  DefaultListableApplicationContext  implements  ApplicationContext  { private  Map < String ,  Object > =  new  ConcurrentHashMap < > ( 128 ) ; private  Map < Class ,  Object > =  new  ConcurrentHashMap < > ( 128 ) ; private  Logger  log =  LoggerFactory . getLogger ( DefaultListableApplicationContext . class ) ; private  String  basePath; public  DefaultListableApplicationContext ( String  basePackage)  { String  packagePath =  basePackage. replaceAll ( "\\." ,  "\\\\" ) ; try  { URL  url =  Thread . currentThread ( ) . getContextClassLoader ( ) . getResource ( packagePath) ; if  ( StringUtils . hasText ( url. getPath ( ) ) )  { String  filePath =  URLDecoder . decode ( url. getFile ( ) ,  "UTF8" ) ; basePath =  filePath. substring ( 0 ,  filePath. length ( )  -  packagePath. length ( ) ) ; loadBeans ( new  File ( filePath) ) ; loadDI ( ) ; } }  catch  ( IOException  e)  { throw  new  RuntimeException ( e) ; } } @Override @Nullable public  Object  getBean ( String  name)  { return  objectsMap. get ( name) ; } @Override @Nullable public  < T > T  getBean ( String  name,  Class < T > )  { Object  obj =  objectsMap. get ( name) ; if  ( obj ==  null )  { Object  bean; if  ( ( bean =  objectsTypeMap. get ( clazz) )  ==  null )  { for  ( Class < ? > :  clazz. getInterfaces ( ) )  { if  ( ( bean =  objectsTypeMap. get ( interfaceClazz) )  !=  null ) return  ( T )  bean; getBean ( name,  interfaceClazz) ; } return  null ; } return  ( T )  bean; } return  clazz. isInstance ( obj)  ?  clazz. cast ( obj)  :  null ; } @Override public  boolean  exists ( String  name)  { return  objectsMap. get ( name)  ==  null  ?  false  :  true ; } @Override public  boolean  exists ( String  name,  Class < ? > )  { if  ( objectsMap. get ( name)  ==  null )  { if  ( objectsTypeMap. get ( clazz)  ==  null )  { for  ( Class < ? > :  clazz. getInterfaces ( ) )  { if  ( objectsTypeMap. get ( interfaceClazz)  !=  null ) return  true ; exists ( name,  interfaceClazz) ; } return  false ; } return  true ; } return  true ; } private  void  loadBeans ( File  file)  { if  ( file. isDirectory ( ) )  { File [ ]  childrenFiles =  file. listFiles ( ) ; if  ( childrenFiles ==  null  ||  childrenFiles. length ==  0 )  { return ; } for  ( File  childFile :  childrenFiles)  { if  ( childFile. isDirectory ( ) )  { loadBeans ( childFile) ; }  else  { String  pathWithClass =  childFile. getAbsolutePath ( ) . substring ( basePath. length ( )  -  1 ) ; if  ( pathWithClass. endsWith ( ".class" ) )  { String  allName =  pathWithClass. replaceAll ( "\\\\" ,  "." ) . replace ( ".class" ,  "" ) ; try  { Class < ? > =  Class . forName ( allName) ; if  ( ! clazz. isInterface ( ) )  { if  ( clazz. getAnnotation ( Component . class )  !=  null )  { Object  instance =  clazz. getConstructor ( ) . newInstance ( ) ; if  ( StringUtils . hasText ( clazz. getAnnotation ( Component . class ) . value ( ) ) )  { String  beanName =  clazz. getAnnotation ( Component . class ) . value ( ) ; objectsMap. put ( beanName,  instance) ; log. warn ( ">>> objectsMap store bean(name,obj) ===> ("  +  beanName +  ","  +  instance +  ")" ) ; if  ( clazz. getInterfaces ( ) . length ==  1 )  { objectsTypeMap. put ( clazz. getInterfaces ( ) [ 0 ] ,  instance) ; log. warn ( ">>> objectsTypeMap store bean(class,obj) ===> ("  +  clazz. getInterfaces ( ) [ 0 ] . getSimpleName ( )  +  ","  +  instance +  ")" ) ; }  else  if  ( clazz. getInterfaces ( ) . length ==  0 )  { objectsTypeMap. put ( clazz,  instance) ; log. warn ( ">>> objectsTypeMap store bean(class,obj) ===> ("  +  clazz. getInterfaces ( ) [ 0 ] . getSimpleName ( )  +  ","  +  instance +  ")" ) ; }  else  { throw  new  NotSupportMoreSuperInterface ( "Not support the bean that has more than two super interfaces." ) ; } } else  if  ( clazz. getInterfaces ( ) . length >  0 )  { String  interfaceName =  clazz. getInterfaces ( ) [ 0 ] . getSimpleName ( ) ; String  beanName =  lowercaseFirstLetter ( interfaceName) ; objectsMap. put ( beanName,  instance) ; log. warn ( ">>> objectsMap store bean(name,obj) ===> ("  +  beanName +  ","  +  instance +  ")" ) ; objectsTypeMap. put ( clazz. getInterfaces ( ) [ 0 ] ,  instance) ; log. warn ( ">>> objectsTypeMap store bean(class,obj) ===> ("  +  clazz. getInterfaces ( ) [ 0 ] . getSimpleName ( )  +  ","  +  instance +  ")" ) ; } else  { String  beanName =  lowercaseFirstLetter ( clazz. getSimpleName ( ) ) ; objectsMap. put ( beanName,  instance) ; log. warn ( ">>> objectsMap store bean(name,obj) ===> ("  +  beanName +  ","  +  instance +  ")" ) ; objectsTypeMap. put ( clazz,  instance) ; log. warn ( ">>> objectsTypeMap store bean(class,obj) ===> ("  +  clazz. getInterfaces ( ) [ 0 ] . getSimpleName ( )  +  ","  +  instance +  ")" ) ; } } } }  catch  ( Exception  e)  { throw  new  RuntimeException ( e) ; } } } } } } private  void  loadDI ( )  { for  ( Map. Entry < String ,  Object > :  objectsMap. entrySet ( ) )  { Object  obj =  entry. getValue ( ) ; Class < ? > =  obj. getClass ( ) ; Field [ ]  fields =  clazz. getDeclaredFields ( ) ; for  ( Field  field :  fields)  { try  { field. setAccessible ( true ) ; if  ( field. getAnnotation ( DI . class )  !=  null )  { Class < ? > [ ]  interfaces =  field. getType ( ) . getInterfaces ( ) ; String  needWiredBeanName; Object  autoWiredBean; if  ( StringUtils . hasText ( needWiredBeanName =  field. getAnnotation ( DI . class ) . value ( ) ) )  { autoWiredBean =  objectsMap. get ( needWiredBeanName) ; if  ( autoWiredBean !=  null )  { field. set ( obj,  autoWiredBean) ; log. warn ( "<<< DI: Class "  +  clazz. getSimpleName ( )  +  " of field named "  +  field. getName ( )  +  " is injected with value of "  +  autoWiredBean +  " from "  +  "objectsMap, by value of annotation @DI" ) ; continue ; }  } needWiredBeanName =  lowercaseFirstLetter ( field. getType ( ) . getSimpleName ( ) ) ; if  ( ( autoWiredBean =  objectsMap. get ( needWiredBeanName) )  !=  null  ||  ( autoWiredBean =  objectsTypeMap. get ( field. getType ( ) ) )  !=  null )  { field. set ( obj,  autoWiredBean) ; log. warn ( "<<< DI: Class "  +  clazz. getSimpleName ( )  +  " of field named "  +  field. getName ( )  +  " is injected with value of "  +  autoWiredBean +  " , by value or type of property itself " ) ; continue ; } if  ( interfaces. length >  0 )  { for  ( Class < ? > :  interfaces)  { String  interfaceClazzName =  interfaceClazz. getSimpleName ( ) ; if  ( interfaceClazz. isAssignableFrom ( field. getType ( ) ) )  { needWiredBeanName =  lowercaseFirstLetter ( interfaceClazzName) ; if  ( ( autoWiredBean =  objectsMap. get ( needWiredBeanName) )  !=  null  ||  ( autoWiredBean =  objectsTypeMap. get ( interfaceClazz) )  !=  null )  { field. set ( obj,  autoWiredBean) ; log. warn ( "<<< DI: Class "  +  clazz. getSimpleName ( )  +  " of field named "  +  field. getName ( )  +  " is injected with value of "  +  autoWiredBean +  ", by value or type of super interface" ) ; } } } continue ; } throw  new  InjectBeanException ( "There occurs an Exception while injecting property filed ["  +  field. getName ( )  +  "] of Class <"  +  clazz. getSimpleName ( )  +  "> , because bean factory doesn't exist the bean named "  +  needWiredBeanName) ; } }  catch  ( IllegalAccessException  e)  { throw  new  RuntimeException ( e) ; } } } } private  String  lowercaseFirstLetter ( String  name)  { return  name. substring ( 0 ,  1 ) . toLowerCase ( )  +  name. substring ( 1 ) ; } } 
public  interface  UserDao  { void  addUser ( User  user) ; 
} 
@Component ( "userDao" ) 
public  class  UserDaoImpl  implements  UserDao  { @Override public  void  addUser ( User  user)  { System . out. println ( ) ; System . out. println ( "------------------>>>执行UserDaoImpl中的addUser方法开始<<<<------------------" ) ; System . out. println ( "\t\t\t\t\t\t名字\t\t\t\t年龄" ) ; System . out. println ( "\t\t\t\t\t\t" + user. getName ( ) + "\t\t\t\t" + user. getAge ( ) ) ; System . out. println ( "------------------>>>执行UserDaoImpl中的addUser方法完毕<<<<------------------" ) ; } 
} public  interface  UserService  { void  add ( ) ; 
} 
@Component ( "userService" ) 
public  class  UserServiceImpl  implements  UserService  { @DI ( "userDao" ) private  UserDaoImpl  userDao; @Override public  void  add ( )  { System . out. println ( "》》》 user service impl execute add method..." ) ; User  user =  new  User ( "张三" ,  25 ) ; userDao. addUser ( user) ; } 
} public  class  InjectBeanException  extends  RuntimeException { public  InjectBeanException ( )  { super ( ) ; } public  InjectBeanException ( String  message)  { super ( message) ; } 
} 
public  class  NotExistsBean  extends  RuntimeException { public  NotExistsBean ( )  { } public  NotExistsBean ( String  message)  { super ( message) ; } 
} 
public  class  NotSupportMoreSuperInterface  extends  RuntimeException { public  NotSupportMoreSuperInterface ( )  { super ( ) ; } public  NotSupportMoreSuperInterface ( String  message)  { super ( message) ; } 
} 
public  class  TestUser  { public  static  void  main ( String [ ]  args)  { DefaultListableApplicationContext  context =  new  DefaultListableApplicationContext ( "com.ypy.context" ) ; UserService  userService =  context. getBean ( "aaa" ,  UserServiceImpl . class ) ; UserDao  userDao =  context. getBean ( "userDaoImpl" ,  UserDao . class ) ; boolean  existFlag =  context. exists ( "aaa" ) ; System . out. println ( "UserService exists ? "  +  existFlag) ; System . out. println ( "从Bean容器中获取aaa对象地址: "  +  userService) ; System . out. println ( "从Bean容器中获取userDao对象地址: "  +  userDao) ; userService. add ( ) ; } 
} 
一月 18, 2024 4:01:20 上午 com.sun.org.slf4j.internal.Logger warn
警告: >>> objectsMap store bean(name,obj) ===> (userDao,com.ypy.context.dao.impl.UserDaoImpl@2b193f2d)
一月 18, 2024 4:01:20 上午 com.sun.org.slf4j.internal.Logger warn
警告: >>> objectsTypeMap store bean(class,obj) ===> (UserDao,com.ypy.context.dao.impl.UserDaoImpl@2b193f2d)
一月 18, 2024 4:01:20 上午 com.sun.org.slf4j.internal.Logger warn
警告: >>> objectsMap store bean(name,obj) ===> (userService,com.ypy.context.service.impl.UserServiceImpl@7a81197d)
一月 18, 2024 4:01:20 上午 com.sun.org.slf4j.internal.Logger warn
警告: >>> objectsTypeMap store bean(class,obj) ===> (UserService,com.ypy.context.service.impl.UserServiceImpl@7a81197d)
一月 18, 2024 4:01:20 上午 com.sun.org.slf4j.internal.Logger warn
警告: <<< DI: Class UserServiceImpl of field named userDao is injected with value of com.ypy.context.dao.impl.UserDaoImpl@2b193f2d from objectsMap, by value of annotation @DI
UserService exists ? false
从Bean容器中获取aaa对象地址: com.ypy.context.service.impl.UserServiceImpl@7a81197d
从Bean容器中获取userDao对象地址: com.ypy.context.dao.impl.UserDaoImpl@2b193f2d
》》》 user service impl execute add method...------------------>>>执行UserDaoImpl中的addUser方法开始<<<<------------------名字				年龄张三				25
------------------>>>执行UserDaoImpl中的addUser方法完毕<<<<------------------Process finished with exit code 0