手写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);
- }
- }
复制代码 依赖注入
- 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);
- }
- }
复制代码 后置处理器
- 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
- @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;
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |