简介
本章节通过手写一个简单的 Spring 框架来加深对 Spring 框架源码以及设计思想的理解;
实现步骤
- BeanScope 枚举代码
public enum BeanScope {
sigleton,
prototype;
}
- AppConfig 配置类
// 定义包扫描路径
@ComponentScan("com.dufu.spring")
public class AppConfig {}
- DufuBeanPostProcessor 后置处理器
@Component
public class DufuBeanPostProcessor implements BeanPostProcessor {@
Override
public Object postProcessorBeforeInitialization(String beanName, Object bean) {
if (beanName.equals("userService")) {
System.out.println("处理 userService 初始化之前 ...");
}
return bean;
}
@Override
public Object postProcessorAfterInitialization(String beanName, Object bean) {
if (beanName.equals("userService")) {
System.out.println("处理 userService 初始化之后 ...");
// 创建代理对象,模拟 AOP 功能
Object proxyInstance = Proxy.newProxyInstance(DufuBeanPostProcessor.class.getClassLoader(),
bean.getClass().getInterfaces(), new InvocationHandler() {@
Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("AOP 切面逻辑 ...");
return method.invoke(bean, args);
}
});
return proxyInstance;
}
return bean;
}
- UserService 接口代码
public interface IUserService {
void test();
}
- OrderService 实例
@Component
public class OrderService {}
- UserService 实例
@Component
public class UserService implements BeanNameAware, InitializingBean, IUserService {@
Autowired
private OrderService orderService;
public void print() {
System.out.println(orderService);
}
@Override
public void setBeanName(String beanName) {
System.out.println("beanName ==> " + beanName);
}
@Override
public void afterPropertiesSet() {
System.out.println("UserService 初始化后其他操作 ...");
}
@Override
public void test() {
System.out.println("调用了 test() 方法");
}
}
- Autowired 注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
String value() default "";
}
- BeanDefinition Bean 的定义工具类
public class BeanDefinition {
// Bean 的类型
private Class type;
// Bean 的范围(多例还是单例)
private String scope;
public Class getType() {
return type;
}
public void setType(Class type) {
this.type = type;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
}
- BeanNameAware 回调接口
public interface BeanNameAware {
void setBeanName(String beanName);
}
- BeanPostProcessor 后置处理器接口
public interface BeanPostProcessor {
// 初始化前
Object postProcessorBeforeInitialization(String beanName, Object bean);
// 初始化后
Object postProcessorAfterInitialization(String beanName, Object bean);
}
- Component 注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String value() default "";
}
- ComponentScan 注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
String value() default "";
}
- DufuApplicationContext Spring 容器核心设计
public class DufuApplicationContext {
// 点符号
private final String SYMBOL_SPOT = ".";
// 左斜线
private final String LEFT_SLASH = "/";
// 右斜线
private final String RIGHT_SLASH = "\\";
// .class 后缀
private final String SUFFIX_CLASS = ".class";
// 配置类
private Class configClass;
// Bean 信息集合
private ConcurrentHashMap <String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap <> ();
// Bean 单例池
private ConcurrentHashMap <String, Object> singletonObjects = new ConcurrentHashMap <> ();
// 后置处理器集合
private List < BeanPostProcessor > beanPostProcessorList = new ArrayList <> ();
public DufuApplicationContext() {}
public DufuApplicationContext(Class configClass) throws Exception {
this.configClass = configClass;
// 判断有没有 @ComponentScan 注解, 并获取扫描路径,解析 Bean 对象信息
if (configClass.isAnnotationPresent(ComponentScan.class)) {
ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
String pkScanValue = componentScanAnnotation.value().equals("") ? configClass.getPackage().getName() : componentScanAnnotation.value();
// 注意: 我们实际上需要的是 out 目录下的路径
String packagePath = pkScanValue.replace(SYMBOL_SPOT, LEFT_SLASH);
ClassLoader classLoader = DufuApplicationContext.class.getClassLoader();
URL resource = classLoader.getResource(packagePath);
// 得到本地项目的绝对路径
// D:\sorftware\idea\workspace\workspace_11\spring-dufu\out\production\spring-dufu\com\dufu\service
File outDirectory = new File(resource.getFile());
if (outDirectory.isDirectory()) {
// 拿到所有编译后的 class 文件
File[] files = outDirectory.listFiles();
for (File file: files) {
String filePath = file.getAbsolutePath();
if (filePath.endsWith(SUFFIX_CLASS)) {
String className = filePath.substring(filePath.lastIndexOf(RIGHT_SLASH) + 1, filePath.lastIndexOf(SUFFIX_CLASS));
Class <?> clazz = classLoader.loadClass(pkScanValue + SYMBOL_SPOT + className);
// 记录后置处理器
if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
BeanPostProcessor instance = (BeanPostProcessor) clazz.newInstance();
beanPostProcessorList.add(instance);
}
// 声明为 Bean 的实体类
if (clazz.isAnnotationPresent(Component.class)) {
Component componentAnnotation = clazz.getAnnotation(Component.class);
// 获取 BeanName
String beanName = componentAnnotation.value().equals("") ? Introspector.decapitalize(clazz.getSimpleName()) : componentAnnotation.value();
// 定义 Bean
BeanDefinition beanDefinition = new BeanDefinition();
// 定义 Bean 的类型
beanDefinition.setType(clazz);
// 定义 Bean 的范围
if (clazz.isAnnotationPresent(Scope.class)) {
Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
beanDefinition.setScope(scopeAnnotation.value());
} else { // 单例 Bean
beanDefinition.setScope(BeanScope.sigleton.toString());
}
// 将定义后的 Bean 存入到单例池
beanDefinitionMap.put(beanName, beanDefinition);
}
}
}
}
}
// 实例化单例 Bean
for (String beanName: beanDefinitionMap.keySet()) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition.getScope().equals(BeanScope.sigleton.toString())) {
Object bean = createBean(beanName, beanDefinition);
singletonObjects.put(beanName, bean);
}
}
}
/**
* 创建 Bean 对象
*/
private Object createBean(String beanName, BeanDefinition beanDefinition) throws Exception {
Class clazz = beanDefinition.getType();
// 利用初始化方法实例化对象
Object instance = clazz.getConstructor().newInstance();
// 依赖注入
for (Field field: clazz.getDeclaredFields()) {
// 如果属性上添加了 @Autowired 注解就注入
if (field.isAnnotationPresent(Autowired.class)) {
field.setAccessible(true);
field.set(instance, getBean(field.getName()));
}
}
// 如果实现了 BeanNameAware 接口, 回调方法
if (instance instanceof BeanNameAware) {
((BeanNameAware) instance).setBeanName(beanName);
}
// 后置处理器, 初始化前
for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) {
instance = beanPostProcessor.postProcessorBeforeInitialization(beanName, instance);
}
// 初始化
if (instance instanceof InitializingBean) {
((InitializingBean) instance).afterPropertiesSet();
}
// BeanPostProcessor(Bean 的后置处理器) 初始化后 AOP
// 后置处理器, 初始化后
for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) {
instance = beanPostProcessor.postProcessorAfterInitialization(beanName, instance);
}
return instance;
}
/**
* 根据名称获取 Bean
*/
public Object getBean(String beanName) throws Exception {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (null == beanDefinition) {
throw new NullPointerException("名为: " + beanName + " 的 Bean 不存在");
}
String scope = beanDefinition.getScope();
if (scope.equals(BeanScope.sigleton.toString())) { // 单例 Bean
Object bean = singletonObjects.get(beanName);
if (null == bean) {
singletonObjects.put(beanName, createBean(beanName, beanDefinition));
}
return bean;
} else { // 多例 Bean
return createBean(beanName, beanDefinition);
}
}
}
- InitializingBean 初始化 Bean 接口
public interface InitializingBean {
void afterPropertiesSet();
}
- Scope 注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
String value() default "";
}
测试一下
public class Test {
public static void main(String[] args) throws Exception {
DufuApplicationContext context = new DufuApplicationContext(AppConfig.class);
// 模拟依赖注入,Aware 回调,初始化
//UserService userService = (UserService)context.getBean("userService");
//System.out.println(userService);
//userService.print();
// 模拟 AOP 功能,调用前需要先注释掉上面的代码
IUserService iUserService = (IUserService) context.getBean("userService");
iUserService.test();
}
}