文章目录
- 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);
}
}