spring框架源码学习
spring源码模仿
创建spring容器准备工作
创建spring容器,用创建spring容器里的api
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class MockKingJayApplication {
private Class configClass;
public MockKingJayApplication(Class configClass){ this.configClass=configClass; }
public Object getBean(String beanName){ return null; } }
|
定义ComponentScan注解
1 2 3 4 5 6 7 8 9
| @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) public @interface ComponentScan {
String value(); }
|
定义Component注解
1 2 3 4 5 6
| @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Component {
String value() default ""; }
|
测试类创建
Uservice
1 2 3 4
| @Component("userService") public class UserService {
}
|
AppConfig
1 2 3 4 5 6 7 8 9 10
|
@ComponentScan("com.mockingjay.service") public class AppConfig {
}
|
Test
1 2 3 4 5 6 7 8 9 10 11
| public class Test {
public static void main(String[] args) {
MockKingJayApplication mockKingJayApplication=new MockKingJayApplication(AppConfig.class);
Object userService = mockKingJayApplication.getBean("userService");
} }
|
扫描逻辑模拟实现
要判断是否有ComponentScan注解
1 2
| ComponentScan componentScan=(ComponentScan) configClass.getDeclaredAnnotation(ComponentScan.class);
|
扫描路径(这里为com.mockingjay.service)
1
| String path=componentScan.value();
|
扫描该路径下所有带component注解的类,如果有,则说明该类是一个bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public MockKingJayApplication(Class configClass){ this.configClass=configClass;
ComponentScan componentScan=(ComponentScan) configClass.getDeclaredAnnotation(ComponentScan.class); String path=componentScan.value(); ClassLoader classLoader=MockKingJayApplication.class.getClassLoader(); URL resource = classLoader.getResource(path.replace(".","/")); File file=new File(resource.getFile()); if(file.isDirectory()){ File[] files = file.listFiles(); for (File f : files) {
String fileName=f.getAbsolutePath(); if(fileName.endsWith(".class")){ String packageName=fileName.substring(fileName.indexOf("com"),fileName.indexOf(".class")). replace("\\" ,"."); Class<?> clazz = null; try { clazz = classLoader.loadClass(packageName); if(clazz.isAnnotationPresent(Component.class)){ } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } }
|
创建scope注解(模仿spring单例bean和原型bean)
1 2 3 4 5 6 7 8 9 10 11 12
|
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Scope { String value(); }
|
beanDefinition过程(spring重要概念):
解析类 – >beanDefinition(bean的一些属性 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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; } }
|
创建单例池和beanDefinition池(单例bean不是单例模式,一个容器中可能有多个该类型的bean(使用bean注解)):
1 2 3
| private ConcurrentHashMap<String,Object> singletonObjectsMap=new ConcurrentHashMap<>(); private ConcurrentHashMap<String,BeanDefinition> beanDefinitionObjectsMap=new ConcurrentHashMap<>();
|
逻辑实现如下(扫描路径下所有带component注解,如果有这个注解,说明这是一个bean,之后创建BeanDefinition对象,如果该对象没有scope注解,则为单例(创建一次不会创建第二次),如果有则获取scope注解里的值放入beanDefiniton对象中,之后将创建好的beanDefiniton放入beanDefinition池中):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| if(file.isDirectory()){ File[] files = file.listFiles(); for (File f : files) {
String fileName=f.getAbsolutePath(); if(fileName.endsWith(".class")){ String packageName=fileName.substring(fileName.indexOf("com"),fileName.indexOf(".class")). replace("\\" ,"."); Class<?> clazz = null; try { clazz = classLoader.loadClass(packageName); if(clazz.isAnnotationPresent(Component.class)){ BeanDefinition beanDefinition=new BeanDefinition();
Component ComponentAnnotation = clazz.getDeclaredAnnotation(Component.class); String beanName=ComponentAnnotation.value();
if(clazz.isAnnotationPresent(Scope.class)){ Scope scopeAnnotation=clazz.getDeclaredAnnotation(Scope.class); beanDefinition.setScope(scopeAnnotation.value()); }else { beanDefinition.setScope("singleton"); } beanDefinition.setClazz(clazz); beanDefinitionObjectsMap.put(beanName,beanDefinition); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } }
|
将扫描方法提取成一个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| private void scan(Class configClass) { ComponentScan componentScan=(ComponentScan) configClass.getDeclaredAnnotation(ComponentScan.class); String path=componentScan.value(); ClassLoader classLoader=MockKingJayApplication.class.getClassLoader(); URL resource = classLoader.getResource(path.replace(".","/")); File file=new File(resource.getFile()); if(file.isDirectory()){ File[] files = file.listFiles(); for (File f : files) {
String fileName=f.getAbsolutePath(); if(fileName.endsWith(".class")){ String packageName=fileName.substring(fileName.indexOf("com"),fileName.indexOf(".class")). replace("\\" ,"."); Class<?> clazz = null; try { clazz = classLoader.loadClass(packageName); if(clazz.isAnnotationPresent(Component.class)){ BeanDefinition beanDefinition=new BeanDefinition();
Component ComponentAnnotation = clazz.getDeclaredAnnotation(Component.class); String beanName=ComponentAnnotation.value();
if(clazz.isAnnotationPresent(Scope.class)){ Scope scopeAnnotation=clazz.getDeclaredAnnotation(Scope.class); beanDefinition.setScope(scopeAnnotation.value()); }else { beanDefinition.setScope("singleton"); } beanDefinition.setClazz(clazz); beanDefinitionObjectsMap.put(beanName,beanDefinition); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } }
|
构造方法(先扫描,在从beanDefinitionObjectsMap找到单例bean放入单例池中)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public MockKingJayApplication(Class configClass){ this.configClass=configClass;
scan(configClass);
for(Map.Entry<String,BeanDefinition> entry:beanDefinitionObjectsMap.entrySet()){ String beanName=entry.getKey(); BeanDefinition beanDefinition=entry.getValue(); if(beanDefinition.getScope().equals("singleton")){ Object bean=createBean(beanDefinition); singletonObjectsMap.put(beanName,bean); } } }
public Object createBean(BeanDefinition beanDefinition){
Class clazz = beanDefinition.getClazz(); try { Object o = clazz.getDeclaredConstructor().newInstance(); return o; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; }
|
getbean方法实现(如果是单例,则在单例池中找到该bean对象,如果不是,调用createBean重写创建一个新的bean)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public Object getBean(String beanName){ if (beanDefinitionObjectsMap.containsKey(beanName)){ BeanDefinition beanDefinition=beanDefinitionObjectsMap.get(beanName); if(beanDefinition.getScope().equals("singleton")){ Object o=singletonObjectsMap.get(beanName); return o; }else { Object bean= createBean(beanDefinition); return bean; } }else{ throw new NullPointerException(); } }
|
creatbean方法实现
准备工作
创建Autowired注解
1 2 3 4 5 6 7
| @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.FIELD}) public @interface AutoWired {
String value() default ""; }
|
创建orderService
1 2 3 4 5
| @Component("orderService") public class OrderService {
}
|
在userService中创建方法,并注入orderservice
1 2 3 4 5 6 7 8 9 10 11
| @Component("userService")
public class UserService {
@AutoWired OrderService orderService;
public void test(){ System.out.println(orderService); } }
|
在测试中输出:
1 2 3 4 5 6 7 8 9 10 11 12
| public class Test {
public static void main(String[] args) {
MockKingJayApplication mockKingJayApplication=new MockKingJayApplication(AppConfig.class);
UserService userService = (UserService) mockKingJayApplication.getBean("userService");
userService.test(); } }
|
createBean方法简单实现(根据属性名注入)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public Object createBean(BeanDefinition beanDefinition){
Class clazz = beanDefinition.getClazz(); try { Object o = clazz.getDeclaredConstructor().newInstance();
for (Field declaredField : clazz.getDeclaredFields()) { if(declaredField.isAnnotationPresent(AutoWired.class)){ Object bean=getBean(declaredField.getName()); if(bean==null){ return new NullPointerException(); } declaredField.setAccessible(true); declaredField.set(o,bean); } }
return o; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; }
|
Aware回调模拟
spring在创建一个bean之后想要获取该bean的名字等:
创建BeanNameAware接口:
1 2 3 4 5
| public interface BeanNameAware {
void setBeanName(String name); }
|
在userService实现该接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Component("userService") public class UserService implements BeanNameAware {
@AutoWired OrderService orderService;
String beanName;
public void test(){ System.out.println(orderService); }
@Override public void setBeanName(String name) { beanName=name; } }
|
在createBean中加入该逻辑
1 2 3 4
| if(o instanceof BeanNameAware){ ((BeanNameAware) o).setBeanName(beanName); }
|
createBean初始化
创建InitializingBean接口
1 2 3 4 5
| public interface InitializingBean {
void afterPropertiesSet() throws Exception; }
|
修改userservice(afterPropertiesSet中的执行内容可以自己修改)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Component("userService") public class UserService implements InitializingBean {
@AutoWired OrderService orderService;
public void test(){ System.out.println(orderService); }
@Override public void afterPropertiesSet() throws Exception { System.out.println("初始化"); } }
|
在createBean中加入该逻辑
1 2 3 4 5 6 7 8
| if(o instanceof InitializingBean){ try { ((InitializingBean) o).afterPropertiesSet(); } catch (Exception e) { e.printStackTrace(); } }
|
beanPostProcessor(bean的后置处理器)
定义接口
1 2 3 4 5 6 7 8 9 10 11
| public interface BeanPostProcessor {
default Object postProcessBeforeInitialization(Object bean, String beanName){ return bean; }
default Object postProcessAfterInitialization(Object bean, String beanName){ return bean; }
}
|
创建类去模拟后置处理器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Component("BeanPostProcessorTest") public class BeanPostProcessorTest implements BeanPostProcessor {
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) {
if(beanName.equals("userService")){ ((UserService)bean).setName("mockingjay is good"); }
return bean; }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) { System.out.println("初始化后 "); return bean; } }
|
在userservice中去模拟
1 2 3 4 5
| String name;
public void setName(String name) { this.name = name; }
|
在扫描容器加入如下判断逻辑
1 2 3 4 5
| if(BeanPostProcessor.class.isAssignableFrom(clazz)){ BeanPostProcessor instance = (BeanPostProcessor) clazz.getDeclaredConstructor().newInstance(); beanPostProcessorList.add(instance); }
|
在createBean下初始化前后加入bean后置处理器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) { beanPostProcessor.postProcessBeforeInitialization(o,beanName); }
if(o instanceof InitializingBean){ try { ((InitializingBean) o).afterPropertiesSet(); } catch (Exception e) { e.printStackTrace(); } }
for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) { beanPostProcessor.postProcessAfterInitialization(o,beanName); }
|
spring AOP 模拟
创建productService和productServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public interface ProductService {
void test();
}
@Component("productService") public class ProductServiceImpl implements ProductService{
@AutoWired OrderService orderService;
@Override public void test() { System.out.println("hello world"); System.out.println(orderService); } }
|
该过程在beanPostProcessor的postProcessAfterInitialization后进行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Override public Object postProcessAfterInitialization(Object bean, String beanName) { System.out.println(beanName); if(beanName.equals("productService")){ Object proxyInstance=Proxy.newProxyInstance(BeanPostProcessorTest.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理逻辑"); method.invoke(bean,args); return null; } }); return proxyInstance; } return bean; } }
|
spring的bean生命周期
创建
class(userServicve.class)–> 推断构造方法(如果有一个有参或者是多个有参但有一个无参,不会报错,其中有参构造器会通过byType(先)和byName 去从spring容器中获取)–> 实例化 –> 对象 –> 属性填充(依赖注入) –> 初始化 afterPropertiesSet() (是否实现InitializingBean)–>(AOP–>代理对象(这个代理对象中没有实例化对象里的属性值,比如userService中注入了orderService,但是这个代理对象没有orderService,而代理对象中target中有属性值) –>(前提是否有AOP操作))–> bean对象
AOP : 1. 把所有的切面找出来,之后放入缓存中(下次直接可以从缓存中找到切面bean)
2. 匹配传入的切点(两步都匹配上,说明使用了AOP)
销毁
spring的事务
两个注解:
1 2 3
| @Configuration
@EnableTransactionManagement
|
在使用事务的方法或者类上加入 @Transactional
出现错误场景:
如果一个类中两个方法,都加上事务,且第二个事务的传播级别为Never(如果有存在事务还存在事务,则会抛出异常),第一方法中调用第二个方法后,执行不会报错。
为什么:因为spring底层会创建代理对像,但执行这两个方法确是被代理对象(target)去执行,被代理对象不会管你是不是加入@Transactional注解,第二个事务则会失效。
如何解决:让代理对象去执行该方法,自己注入自己(这里注入的是代理对象,而不是该类型的bean对象)