手写Spring底层机制
手写Spring底层机制
IOC容器
//定义 BeanDefinitionMap 存放 beanDefinition
private ConcurrentHashMap<String,BeanDefinition> beanDefinitionMap =
new ConcurrentHashMap<>();
//定义 singletonObjects 存放 单例
private ConcurrentHashMap<String,Object> singletonObjects =
new ConcurrentHashMap<>();
//定义beanPostProcessorList 存放 BeanPostProcessor
private ArrayList<BeanPostProcessor> beanPostProcessorList=
new ArrayList<>();
构造器
//构造器
public ZyApplicationContext(Class configClass) {
this.configClass = configClass;
beanDefinitionsByScan();
//初始化单例池
initSingletonObjects();
}
扫描包
private void beanDefinitionsByScan() {
//获得扫描的包
ComponentScan componentScan =
(ComponentScan)this.configClass.getDeclaredAnnotation(ComponentScan.class);
//获取路径
String path = componentScan.value();
path = path.replace(".","/");
//获取工作路径
ClassLoader classLoader = ZyApplicationContext.class.getClassLoader();
URL resource = classLoader.getResource(path);
File file = new File(resource.getFile());
if (file.isDirectory()){
File[] files = file.listFiles();
for (File f : files) {
//获取绝对路径
String fileAbsolutePath = f.getAbsolutePath();
if (fileAbsolutePath.endsWith(".class")) {
//获取className
String className = fileAbsolutePath.substring(fileAbsolutePath.lastIndexOf("\\") + 1, fileAbsolutePath.indexOf(".class"));
String fullPath = path.replace("/", ".") + "." + className;
try {
Class<?> clazz = classLoader.loadClass(fullPath);
if (clazz.isAnnotationPresent(Component.class)) {
//初始化beanPostProcessorList
if (BeanPostProcessor.class.isAssignableFrom(clazz)){
BeanPostProcessor beanPostProcessor =
(BeanPostProcessor)clazz.newInstance();
beanPostProcessorList.add(beanPostProcessor);
continue;
}
//处理className
String value = clazz.getDeclaredAnnotation(Component.class).value();
if ("".equals(value)){
className = StringUtils.uncapitalize(className);
}else {
className = value;
}
System.out.println("是一个bean 类名= " + className);
//设置 beanDefinition
BeanDefinition beanDefinition = new BeanDefinition();
//设置scope
if (clazz.isAnnotationPresent(Scope.class)){
beanDefinition.setScope(clazz.getDeclaredAnnotation(Scope.class).value());
}else{
beanDefinition.setScope("singleton");
}
beanDefinition.setClazz(clazz);
//放入 beanDefinitionMap
beanDefinitionMap.put(className,beanDefinition);
} else {
System.out.println("不是一个bean 类名= " + className);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
}
初始化单例池
private void initSingletonObjects() {
Enumeration<String> keys = beanDefinitionMap.keys();
while (keys.hasMoreElements()){
String beanName = keys.nextElement();
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
String scope = beanDefinition.getScope();
if ("singleton".equals(scope)){
Object bean = createBean(beanDefinition,beanName);
singletonObjects.put(beanName,bean);
}
}
}
getBean()
public Object getBean(String name){
if (beanDefinitionMap.containsKey(name)){
BeanDefinition beanDefinition = beanDefinitionMap.get(name);
String scope = beanDefinition.getScope();
if ("singleton".equals(scope)){
return singletonObjects.get(name);
}else{
return createBean(beanDefinition,name);
}
}
return null;
}
createBean()
private Object createBean(BeanDefinition beanDefinition,String beanName){
try {
Class clazz = beanDefinition.getClazz();
Object instance = clazz.getDeclaredConstructor().newInstance();
return instance;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
依赖注入
-
加入到createBean()中
private Object createBean(BeanDefinition beanDefinition,String beanName){
try {
Class clazz = beanDefinition.getClazz();
Object instance = clazz.getDeclaredConstructor().newInstance();
//依赖注入
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
if (declaredField.isAnnotationPresent(Autowired.class)){
if (declaredField.getDeclaredAnnotation(Autowired.class).required()){
//获的字段名
String fieldName = declaredField.getName();
//获取实例
Object bean = getBean(fieldName);
declaredField.setAccessible(true);
declaredField.set(instance,bean);
}
}
}
return instance;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
后置处理器
-
加入到createBean()中
private Object createBean(BeanDefinition beanDefinition,String beanName){
try {
Class clazz = beanDefinition.getClazz();
Object instance = clazz.getDeclaredConstructor().newInstance();
//依赖注入
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
if (declaredField.isAnnotationPresent(Autowired.class)){
if (declaredField.getDeclaredAnnotation(Autowired.class).required()){
//获的字段名
String fieldName = declaredField.getName();
//获取实例
Object bean = getBean(fieldName);
declaredField.setAccessible(true);
declaredField.set(instance,bean);
}
}
}
//后置处理器 before()
//遍历 beanPostProcessorList
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
Object current = beanPostProcessor.
postProcessBeforeInitialization(instance, beanName);
if (current!=null){
instance = current;
}
}
//初始化bean
if (instance instanceof InitializingBean){
try {
((InitializingBean)instance).afterPropertiesSet();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//后置处理器 after()
//遍历 beanPostProcessorList
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
Object current = beanPostProcessor.
postProcessAfterInitialization(instance, beanName);
if (current!=null){
instance = current;
}
}
System.out.println("");
System.out.println("-------------------------------------");
System.out.println("");
return instance;
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
AOP
-
AOP需要在后置处理器的before方法中实现
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("ZyBeanPostProcessor后置处理器-After-beanName= "+beanName);
//aop实现
if("smartDog".equals(beanName)) {
Object proxyInstance = Proxy.newProxyInstance(ZyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
if ("getSum".equals(method.getName())) {
SmartAnimalAspect.showBeginLog();
result = method.invoke(bean, args);
SmartAnimalAspect.showBeginLog();
}else {
result = method.invoke(bean, args);//执行目标方法
}
return result;
}
});
return proxyInstance;
}
return bean;
}
几个Spring的问题
1.单例/多例怎么实现的?@scope为什么可以实现?
回答:@scope 的value属性可以设置为singleton /prototype
通过getBean()方法 如果bean中的属性scope为singleton 就从单例池直接拿,如果是prototype 就调用createBean()创建一个实例
2.如何实现依赖注入?@Autowired Spring容器如何实现依赖注入?
回答: 遍历clazz的所有属性 通过@Autowired注解 如果有 先获取字段名 再通过getBean()获取对应的bean 最后用filed.set()方法将实例的该属性设置为 获取到的bean 实现依赖注入
3.后置处理器 为什么在创建bean 时 调用bean 的 init方法初始化前/后 调用?
//后置处理器 before()
//遍历 beanPostProcessorList
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
Object current = beanPostProcessor.
postProcessBeforeInitialization(instance, beanName);
if (current!=null){
instance = current;
}
}
//初始化bean
if (instance instanceof InitializingBean){
try {
((InitializingBean)instance).afterPropertiesSet();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//后置处理器 after()
//遍历 beanPostProcessorList
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
Object current = beanPostProcessor.
postProcessAfterInitialization(instance, beanName);
if (current!=null){
instance = current;
}
}
4.后置处理器和AOP有什么关系,Spring Aop如何实现??
回答:aop的实现实在后置处理器的before中实现的,底层使用动态代理
//aop实现
if("smartDog".equals(beanName)) {
Object proxyInstance = Proxy.newProxyInstance(ZyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
if ("getSum".equals(method.getName())) {
SmartAnimalAspect.showBeginLog();
result = method.invoke(bean, args);
SmartAnimalAspect.showBeginLog();
}else {
result = method.invoke(bean, args);//执行目标方法
}
return result;
}
});
return proxyInstance;
}
return bean;