源码地址
该简易Spring框架实现的功能有
- 容器启动
- 包扫描
- 单例、多例Bean
- Bean的创建
- 依赖注入
- Aware回调函数
- 初始化
- 后处理器
- AOP
目录结构如下,service包为模拟业务逻辑,spring包为spring的实现(核心),其中ApplicationContext为核心类。
package com.ego.spring;
import java.beans.Introspector;
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;
/**
* @author 袁梦达
*/
public class ApplicationContext {
//配置文件 扫描包
private Class configClass;
//bean工厂
private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
//单例bean
private ConcurrentHashMap<String, Object> singletonMap = new ConcurrentHashMap<>();
//后处理器
private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();
public ApplicationContext(Class configClass){
this.configClass = configClass;
//扫描
if(configClass.isAnnotationPresent(ComponentScan.class)){
//获取ComponentScan的值
ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
//com.ego.service
String scanPath = componentScanAnnotation.value();
//com/ego/service
scanPath = scanPath.replace(".", "/");
//去out文件夹里找到扫描的包
ClassLoader classLoader = ApplicationContext.class.getClassLoader();
URL resource = classLoader.getResource(scanPath);
//扫描包里每一个class文件是否为Bean
File file = new File(resource.getFile());
if(file.isDirectory()){
for (File f : file.listFiles()) {
String fileName = f.getAbsolutePath();
if(fileName.endsWith(".class")){
String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
className = className.replace("\\", ".");
try {
Class<?> clazz = classLoader.loadClass(className);
//判断是否为Bean
if(clazz.isAnnotationPresent(Component.class)){
//如果是后处理器则加入list中
if(BeanPostProcessor.class.isAssignableFrom(clazz)){
BeanPostProcessor instance = (BeanPostProcessor) clazz.getConstructor().newInstance();
beanPostProcessorList.add(instance);
}
Component componentAnnotation = clazz.getAnnotation(Component.class);
String beanName = componentAnnotation.value();
//默认Bean的name
if("".equals(beanName)){
beanName = Introspector.decapitalize(clazz.getSimpleName());
}
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setClazz(clazz);
//作用域
if(clazz.isAnnotationPresent(Scope.class)){
Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
beanDefinition.setScope(scopeAnnotation.value());
}else{
beanDefinition.setScope("singleton");
}
beanDefinitionMap.put(beanName, beanDefinition);
}
} catch (ClassNotFoundException | InvocationTargetException | InstantiationException |
IllegalAccessException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
}
}
//将所有单例Bean加入到单例池
for (String beanName : beanDefinitionMap.keySet()) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if("singleton".equals(beanDefinition.getScope())){
Object bean = createBean(beanName, beanDefinition);
singletonMap.put(beanName, bean);
}
}
}
private Object createBean(String beanName, BeanDefinition beanDefinition){
Class clazz = beanDefinition.getClazz();
Object bean = null;
try {
//实例化
bean = clazz.getConstructor().newInstance();
//依赖注入
for (Field field : clazz.getFields()) {
if(field.isAnnotationPresent(Autowired.class)){
field.setAccessible(true);
field.set(bean, getBean(field.getName()));
}
}
//执行回调接口
if(bean instanceof BeanNameAware){
((BeanNameAware)bean).setBeanName(beanName);
}
//前置处理器
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
bean = beanPostProcessor.postProcessorBeforeInitialization(beanName, bean);
}
//初始化
if(bean instanceof InitializingBean){
((InitializingBean)bean).afterPropertiesSet();
}
//后置处理器
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
bean = beanPostProcessor.postProcessorAfterInitialization(beanName, bean);
}
} catch (InstantiationException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
return bean;
}
public Object getBean(String beanName){
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if(beanDefinition == null){
throw new NullPointerException("bean不存在");
}else {
String scope = beanDefinition.getScope();
if("singleton".equals(scope)){
//单例Bean直接从单例池中获取
Object bean = singletonMap.get(beanName);
//此条件发生在初始化容器时,生成单例Bean的时候
//在某个Bean依赖注入时,如果被注入的单例Bean还没有实例化,
//那么就要先实例化被注入的单例Bean,再实例化当前Bean
if(bean == null){
bean= createBean(beanName, beanDefinition);
}
return bean;
}else{
return createBean(beanName, beanDefinition);
}
}
}
}
package com.ego.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 袁梦达
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
}
package com.ego.spring;
/**
* @author 袁梦达
*/
public class BeanDefinition {
private Class clazz;
private String scope;
public Class getClazz() {
return clazz;
}
public void setClazz(Class clazz) {
this.clazz = clazz;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
}
package com.ego.spring;
public interface BeanNameAware {
void setBeanName(String beanName);
}
package com.ego.spring;
public interface BeanPostProcessor {
Object postProcessorBeforeInitialization(String beanName, Object bean);
Object postProcessorAfterInitialization(String beanName, Object bean);
}
package com.ego.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 袁梦达
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String value() default "";
}
package com.ego.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 袁梦达
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
String value() default "";
}
package com.ego.spring;
/**
* @author 袁梦达
*/
public interface InitializingBean {
void afterPropertiesSet();
}
package com.ego.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 袁梦达
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
String value() default "";
}
package com.ego.service;
import com.ego.spring.BeanPostProcessor;
import com.ego.spring.Component;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessorBeforeInitialization(String beanName, Object bean) {
if(beanName.equals("userService")){
System.out.println("postProcessorBeforeInitialization...");
}
return bean;
}
@Override
public Object postProcessorAfterInitialization(String beanName, Object bean) {
if(beanName.equals("userService")){
System.out.println("postProcessorAfterInitialization...");
return Proxy.newProxyInstance(MyBeanPostProcessor.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 bean;
}
}