手写Spring
自定义使用类和接口
UserService
BeanNameAware
实现回调设置BeanName
的功能setBeanName
InitializingBean
为Bean
创建时,进行一些初始化afterPropertiesSet
@Component("userService")
public class UserService implements BeanNameAware, InitializingBean, UserInterface {
@Autowired
private OrderService orderService;
private String beanName;
private String name;
public void test() {
System.out.println(orderService);
}
@Override
public void setBeanName(String beanName) {
this.beanName = beanName;
}
@Override
public void afterPropertiesSet() {
System.out.println("afterPropertiesSet...");
}
}
UserInterface
public interface UserInterface {
public void test();
}
OrderService
@Component
public class OrderService {
}
自定义注解
ComponentScan
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
String value() default "";
}
Component
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String value() default "";
}
Autowired
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
}
Scope
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
String value() default "";
}
自定义接口
BeanNameAware
public interface BeanNameAware {
public void setBeanName(String beanName);
}
InitializingBean
public interface InitializingBean {
public void afterPropertiesSet();
}
BeanPostProcessor
public interface BeanPostProcessor {
public Object postProcessBeforeInitialization(String beanName, Object bean);
public Object postProcessAfterInitialization(String beanName, Object bean);
}
InitBeanPostProcessor
- 实现了
BeanPostProcessor
,维护Bean
的初始化过程,需要自动注册到IOC容器中
@Component
public class InitBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(String beanName, Object bean) {
if (beanName.equals("userService")) {
System.out.println("userService" + " - " + bean + " - postProcessBeforeInitialization");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(String beanName, Object bean) {
if (beanName.equals("userService")) {
Object proxyInstance = Proxy.newProxyInstance(bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("postProcessAfterInitialization - Proxy");
method.invoke(bean, args);
return null;
}
});
return proxyInstance;
}
return bean;
}
}
配置类
@ComponentScan("com.java.service")
public class AppConfig {
}
BeanDefinition
public class BeanDefinition {
private Class type;
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;
}
}
Context
SpringIOC
容器,其实就是Context
上下文
- 代码按标题分割了,合起来就好(提醒自己)
维护相关信息的集合
public class InitSpringApplicationContext {
private Class configClass;
private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();
private ArrayList<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();
处理配置类的信息
- 实际目的是为了获取配置类的上,需要扫描的包下的
class
文件
public InitSpringApplicationContext(Class configClass) {
this.configClass = configClass
//扫描
//获取扫描路径,获取bean beanDefinition
if (configClass.isAnnotationPresent(ComponentScan.class)) {
ComponentScan componentScan = (ComponentScan) configClass.getAnnotation(ComponentScan.class)
String scanPath = componentScan.value()
scanPath = scanPath.replace(".", "/")
//需要扫描包下面的class,还需要是`out下`经过编译过的class字节码文件
ClassLoader classLoader = InitSpringApplicationContext.class.getClassLoader()
// /Users/mzx/Desktop/java/spring-source/init-spring/out/production/init-spring + /scanPath
// 项目的输出路径 + 扫描路径
URL resource = classLoader.getResource(scanPath)
File file = new File(resource.getFile())
if (file.isDirectory()) { //当前是否是文件夹
File[] files = file.listFiles()
//输出项目的绝对路径/Users/mzx/Desktop/java/spring-source/init-spring/out/production/init-spring/
int len = classLoader.getResource("").getPath().length()
实例化Bean
- 获取全类名
- 处理后置处理器并加入
beanPostProcessorList
- 获取
beanName
,默认为首字母小写,用Introspector
处理
- 生成对应的
beanDefinition
,保存在beanDefinitionMap
for (File f : files) {
String fileName = f.getAbsolutePath();
if (fileName.endsWith(".class")) {
String className = fileName.substring(len, fileName.indexOf(".class"));
className = className.replace("/", ".");
try {
Class<?> clazz = classLoader.loadClass(className);
if (clazz.isAnnotationPresent(Component.class)) {
if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
BeanPostProcessor instance = (BeanPostProcessor) clazz.newInstance();
beanPostProcessorList.add(instance);
continue;
}
String beanName = clazz.getAnnotation(Component.class).value();
if (beanName.equals("")) {
beanName = Introspector.decapitalize(clazz.getSimpleName());
}
BeanDefinition beanDefinition = new BeanDefinition();
if (clazz.isAnnotationPresent(Scope.class)) {
String scope = clazz.getAnnotation(Scope.class).value();
beanDefinition.setScope(scope);
} else {
beanDefinition.setScope("singleton");
}
beanDefinition.setType(clazz);
beanDefinitionMap.put(beanName, beanDefinition);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
处理单例Bean
- 直接创建出来,且只创建一份
- (其实可以不用这一步)
for (String beanName : beanDefinitionMap.keySet()) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition.getScope().equals("singleton")) {
Object bean = createBean(beanName, beanDefinition);
singletonObjects.put(beanName, bean);
}
}
}
createBean
- 真正进行
Bean
的实例化
- 处理依赖注入
- 回调赋值
beanName
- 进行初始化前的操作
- 进行初始化
- 进行初始化后的操作,返回了一个代理对象
private Object createBean(String beanName, BeanDefinition beanDefinition) {
Class clazz = beanDefinition.getType();
try {
Object instance = clazz.getConstructor().newInstance();
for (Field f : clazz.getDeclaredFields()) {
if (f.isAnnotationPresent(Autowired.class)) {
f.setAccessible(true);
f.set(instance, getBean(f.getName()));
}
}
if (instance instanceof BeanNameAware) {
((BeanNameAware) instance).setBeanName(beanName);
}
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
instance = beanPostProcessor.postProcessBeforeInitialization(beanName, instance);
}
if (instance instanceof InitializingBean) {
((InitializingBean) instance).afterPropertiesSet();
}
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
instance = beanPostProcessor.postProcessAfterInitialization(beanName, instance);
}
return instance;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
getBean
- 单例
Bean
,从集合中获取,没有创建
- 多例
Bean
,每次要用都创建
public Object getBean(String beanName) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition == null) {
throw new NullPointerException();
} else {
String scope = beanDefinition.getScope();
if (scope.equals("singleton")) {
Object bean = singletonObjects.get(beanName);
if (bean == null) {
bean = createBean(beanName, beanDefinition);
singletonObjects.put(beanName, bean);
}
return bean;
} else {
return createBean(beanName, beanDefinition);
}
}
}
}
使用
public class Test {
public static void main(String[] args) {
InitSpringApplicationContext isac = new InitSpringApplicationContext(AppConfig.class);
UserInterface userService = (UserInterface) isac.getBean("userService");
userService.test();
}
}