文章目录 1.实现初始化方法 1.目录 2.InitializingBean.java 3.MonsterService.java 实现初始化接口 4.SunSpringApplicationContext.java 调用初始化方法 5.测试 2.实现后置处理器 1.目录 2.BeanPostProcessor.java 后置处理器接口 3.SunBeanProcessor.java 自定义后置处理器 4.SunSpringApplicationContext.java 具体实现 1.定义一个存储后置处理器的List 2.在扫描bean的时候将后置处理器放到List中 3.初始化bean前后使用调用后置处理器进行处理 4.测试 5.完整代码
1.实现初始化方法
1.目录
2.InitializingBean.java
package com. sunxiansheng. sunspring. processor ;
public interface InitializingBean { void afterPropertiesSet ( ) ; }
3.MonsterService.java 实现初始化接口
package com. sunxiansheng. sunspring. compent ; import com. sunxiansheng. sunspring. annotation. Component ;
import com. sunxiansheng. sunspring. annotation. Resource ;
import com. sunxiansheng. sunspring. annotation. Scope ;
import com. sunxiansheng. sunspring. annotation. myenum. MyScope ;
import com. sunxiansheng. sunspring. processor. InitializingBean ;
import org. slf4j. Logger ;
import org. slf4j. LoggerFactory ;
@Component
@Scope ( value = MyScope . PROTOTYPE )
public class MonsterService implements InitializingBean { private static final Logger log = LoggerFactory . getLogger ( MonsterService . class ) ; @Resource private MonsterDao monsterDao; public void query ( ) { log. info ( "MonsterService调用MonsterDao" ) ; monsterDao. query ( ) ; } @Override public void afterPropertiesSet ( ) { log. info ( "MonsterService初始化完成..." ) ; } }
4.SunSpringApplicationContext.java 调用初始化方法
5.测试
2.实现后置处理器
1.目录
2.BeanPostProcessor.java 后置处理器接口
package com. sunxiansheng. sunspring. processor ;
public interface BeanPostProcessor { default Object postProcessBeforeInitialization ( Object bean, String beanName) { return bean; } default Object postProcessAfterInitialization ( Object bean, String beanName) { return bean; } }
3.SunBeanProcessor.java 自定义后置处理器
package com. sunxiansheng. sunspring. compent ; import com. sunxiansheng. sunspring. annotation. Component ;
import com. sunxiansheng. sunspring. processor. BeanPostProcessor ;
import org. slf4j. Logger ;
import org. slf4j. LoggerFactory ;
@Component
public class SunBeanProcessor implements BeanPostProcessor { private static final Logger log = LoggerFactory . getLogger ( SunBeanProcessor . class ) ; @Override public Object postProcessBeforeInitialization ( Object bean, String beanName) { log. info ( "SunBeanProcessor postProcessBeforeInitialization..." + beanName + "=>" + bean. getClass ( ) ) ; return null ; } @Override public Object postProcessAfterInitialization ( Object bean, String beanName) { log. info ( "SunBeanProcessor postProcessAfterInitialization..." + beanName + "=>" + bean. getClass ( ) ) ; return null ; } }
4.SunSpringApplicationContext.java 具体实现
1.定义一个存储后置处理器的List
2.在扫描bean的时候将后置处理器放到List中
3.初始化bean前后使用调用后置处理器进行处理
4.测试
5.完整代码
package com. sunxiansheng. sunspring. ioc ; import com. sunxiansheng. sunspring. annotation. Component ;
import com. sunxiansheng. sunspring. annotation. ComponentScan ;
import com. sunxiansheng. sunspring. annotation. Resource ;
import com. sunxiansheng. sunspring. annotation. Scope ;
import com. sunxiansheng. sunspring. annotation. myenum. MyScope ;
import com. sunxiansheng. sunspring. processor. BeanPostProcessor ;
import com. sunxiansheng. sunspring. processor. InitializingBean ;
import org. slf4j. Logger ;
import org. slf4j. LoggerFactory ; import java. io. File ;
import java. lang. reflect. Field ;
import java. lang. reflect. InvocationTargetException ;
import java. net. URL ;
import java. util. ArrayList ;
import java. util. List ;
import java. util. concurrent. ConcurrentHashMap ;
public class SunSpringApplicationContext { private static final Logger log = LoggerFactory . getLogger ( SunSpringApplicationContext . class ) ; private ConcurrentHashMap < String , BeanDefintion > beanDefintionMap = new ConcurrentHashMap < > ( ) ; private ConcurrentHashMap < String , Object > singletonObjects = new ConcurrentHashMap < > ( ) ; private List < BeanPostProcessor > beanPostProcessorList = new ArrayList < > ( ) ; public SunSpringApplicationContext ( Class < ? > configClass) throws ClassNotFoundException , InstantiationException , IllegalAccessException { beanDefinitionByScan ( configClass) ; initSingletonObjects ( ) ; } private void populateBeans ( Object bean) { Class < ? > clazz = bean. getClass ( ) ; Field [ ] fields = clazz. getDeclaredFields ( ) ; for ( Field field : fields) { if ( field. isAnnotationPresent ( Resource . class ) ) { String fieldName = field. getName ( ) ; Object beanObject = null ; BeanDefintion beanDefintion = beanDefintionMap. get ( fieldName) ; try { beanObject = getBean ( fieldName) ; } catch ( Exception e) { throw new RuntimeException ( e) ; } field. setAccessible ( true ) ; try { field. set ( bean, beanObject) ; log. info ( "依赖注入成功:{} => {}.{}" , beanObject. getClass ( ) , clazz, fieldName) ; } catch ( IllegalAccessException e) { e. printStackTrace ( ) ; } } } } private void initSingletonObjects ( ) { beanDefintionMap. forEach ( ( beanName, beanDefintion) -> { try { Object bean = createBean ( beanDefintion) ; if ( bean != null ) { singletonObjects. put ( beanName, bean) ; } } catch ( Exception e) { e. printStackTrace ( ) ; } } ) ; log. info ( "根据bean定义信息初始化单例池:{}" , singletonObjects) ; } public Object getBean ( String name) throws Exception { BeanDefintion beanDefintion = beanDefintionMap. get ( name) ; if ( beanDefintion == null ) { throw new NullPointerException ( "在bean定义中没有找到bean对象" ) ; } MyScope scope = beanDefintion. getScope ( ) ; Object bean = null ; if ( scope == MyScope . SINGLETON ) { log. info ( "getBean单例对象:{}" , singletonObjects. get ( name) ) ; bean = singletonObjects. get ( name) ; } else { bean = createProtoTypeBean ( beanDefintion) ; } populateBeans ( bean) ; Object current = bean; for ( BeanPostProcessor beanPostProcessor : beanPostProcessorList) { Object bean1 = beanPostProcessor. postProcessBeforeInitialization ( bean, name) ; if ( bean1 != null ) { current = bean1; } } init ( current) ; for ( BeanPostProcessor beanPostProcessor : beanPostProcessorList) { bean = beanPostProcessor. postProcessAfterInitialization ( current, name) ; if ( bean == null ) { bean = current; } } log. info ( "getBean多例对象:{}" , bean) ; return bean; } public void init ( Object bean) { if ( bean instanceof InitializingBean ) { ( ( InitializingBean ) bean) . afterPropertiesSet ( ) ; } } private Object createBean ( BeanDefintion beanDefintion) throws Exception { Class < ? > clazz = beanDefintion. getClazz ( ) ; if ( beanDefintion. getScope ( ) == MyScope . PROTOTYPE ) { return null ; } Object bean = clazz. getDeclaredConstructor ( ) . newInstance ( ) ; return bean; } private static Object createProtoTypeBean ( BeanDefintion beanDefintion) throws InstantiationException , IllegalAccessException , InvocationTargetException , NoSuchMethodException { Class < ? > clazz = beanDefintion. getClazz ( ) ; Object bean = clazz. getDeclaredConstructor ( ) . newInstance ( ) ; return bean; } private void beanDefinitionByScan ( Class < ? > configClass) { ComponentScan componentScan = configClass. getDeclaredAnnotation ( ComponentScan . class ) ; String path = componentScan. packagePath ( ) ; log. info ( "扫描的包路径:{}" , path) ; ClassLoader classLoader = SunSpringApplicationContext . class . getClassLoader ( ) ; path = path. replace ( "." , "/" ) ; URL resource = classLoader. getResource ( path) ; File file = new File ( resource. getFile ( ) ) ; if ( file. isDirectory ( ) ) { File [ ] files = file. listFiles ( ) ; for ( File f : files) { String absolutePath = f. getAbsolutePath ( ) ; if ( absolutePath. endsWith ( ".class" ) ) { String className = extractClassName ( absolutePath) ; String fullPath = path. replace ( "/" , "." ) + "." + className; Class < ? > aClass = null ; try { aClass = classLoader. loadClass ( fullPath) ; } catch ( ClassNotFoundException e) { throw new RuntimeException ( e) ; } if ( aClass. isAnnotationPresent ( Component . class ) ) { log. info ( "扫描到Spring Bean:{}" , aClass) ; if ( BeanPostProcessor . class . isAssignableFrom ( aClass) ) { Object o = null ; try { o = aClass. getDeclaredConstructor ( ) . newInstance ( ) ; } catch ( Exception e) { log. info ( "BeanPostProcessor实例化失败:{}" , e) ; } if ( o instanceof BeanPostProcessor ) { beanPostProcessorList. add ( ( BeanPostProcessor ) o) ; } log. info ( "BeanPostProcessor实例化成功:{}" , o) ; continue ; } BeanDefintion beanDefintion = new BeanDefintion ( ) ; if ( aClass. isAnnotationPresent ( Scope . class ) ) { Scope scope = aClass. getDeclaredAnnotation ( Scope . class ) ; MyScope value = scope. value ( ) ; beanDefintion. setScope ( value) ; } else { beanDefintion. setScope ( MyScope . SINGLETON ) ; } beanDefintion. setClazz ( aClass) ; Component component = aClass. getDeclaredAnnotation ( Component . class ) ; String beanName = component. value ( ) ; if ( "" . equals ( beanName) ) { beanName = className. substring ( 0 , 1 ) . toLowerCase ( ) + className. substring ( 1 ) ; } beanDefintionMap. put ( beanName, beanDefintion) ; } else { log. info ( "这不是一个Spring Bean={}" , aClass) ; } } } } log. info ( "将bean定义信息放到beanDefintionMap:{}" , beanDefintionMap) ; } private String extractClassName ( String filePath) { int lastSlashIndex = filePath. lastIndexOf ( '/' ) ; int lastDotIndex = filePath. lastIndexOf ( '.' ) ; return filePath. substring ( lastSlashIndex + 1 , lastDotIndex) ; } }