spring 详解三 IOC(spring实例化及后处理器)

这篇具有很好参考价值的文章主要介绍了spring 详解三 IOC(spring实例化及后处理器)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Spring实例化基本流程

Spring在容器初始化的时候,读取XMl配置,将其封装成BeanDefinition(Bean定义)对象,描述所有bean的信息

BeanDefinition会注册存储到beanDefinitionMap集合中

Spring框架遍历beanDefinitionMap,使用反射创建Bean实例对象

创建好之后的对象存储在singletonObjects的map集合中,当getBean时,从该map中取出实例bean对象返回

spring 详解三 IOC(spring实例化及后处理器),springBoot,spring,数据库,sql

Spring配置文件中的配置项都能在BeanDefinition对象中找到 

spring 详解三 IOC(spring实例化及后处理器),springBoot,spring,数据库,sql

BeanDefinition是一个接口,我们使用RootBeanDefinition即可

spring 详解三 IOC(spring实例化及后处理器),springBoot,spring,数据库,sql

 Spring中的两个后处理器

Spring中提供两个后处理器,让我们能够介入实例化流程,动态注册BeanDefinition,动态修改BeanDefinition,以及动态修改Bean的作用

BeanFactoryPostProcessor:Bean工厂后处理器,在beanDefinitionMap填充完毕,还未反射创建对象之前执行

BeanPostProcessor:Bean后处理器 ,在Bean实例化之后,填充至singletonObjects之前执行,一但添加至singletonObjects意味着不能改变,有一个before和after,中间隔着初始化方法的执行。

一个在还未创建对象之前,一个在创建对象之后

Bean工厂后处理器 BeanFactoryPostProcessor

BeanFactoryPostProcessor是一个接口,实现了该接口的类只要交由spring容器管理的话,那么spring就会回调该接口的方法,用于对BeanDefinition注册和修改

package com.tech.test.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;

public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("BeanDefinitionMap填充完毕之后执行该方法");
        // 创建一个BeanDefinition 
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClassName("com.tech.test.test.bean.DI");
        // 查看继承关系图ConfigurableListableBeanFactory就是DefaultListableBeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
        // 注册Bean
        defaultListableBeanFactory.registerBeanDefinition("userService",rootBeanDefinition);
        
    }
}
 <bean id="userService"  name="aaa,bbb"  class="com.tech.test.service.impl.UserServiceImpl" ></bean>
<bean  class="com.tech.test.processor.MyBeanFactoryProcessor "></bean>

需要在配置文件中配置交给spring管理,这个示例 我们动态的修改对象userService为DI对象,当我们getBean时,Bean已经被修改为DI对象

spring提供了专门注册BeanDefinitionMap的接口,BeanDefinitionRegistryPostProcessor,看下继承关系,它是BeanFactoryPostProcessor 的子接口

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.beans.factory.support;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}

演示相同功能 

package com.tech.test.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;

public class MyNoCastProcessor implements BeanDefinitionRegistryPostProcessor {

    // 执行顺序早于postProcessBeanFactory 简记为 谁在上边谁先执行
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        // 创建一个BeanDefinition
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClassName("com.tech.test.test.bean.DI");
        // 注册Bean
        beanDefinitionRegistry.registerBeanDefinition("userService",rootBeanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}
<bean id="userService"  name="aaa,bbb"  class="com.tech.test.service.impl.UserServiceImpl" ></bean>

<bean id="process" class="com.tech.test.processor.MyNoCastProcessor"></bean>

示例:定义自定义注解实现注册对象,配置就不列举啦,需要在对象未创建之前加入Bean定义信息

自定义注解

package com.tech.test.anotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyComponent {

    String value();
}

 加上注解

package com.tech.test.testbean;


import com.tech.test.anotation.MyComponent;

@MyComponent("ceshi")
public class TestAnnotation {
}

 解析注解

package com.tech.test.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;

public class ParseMyComponentProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        // 这里的全限定类名和注解中的名称应该扫描包得到,这里暂时写死
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        rootBeanDefinition.setBeanClassName("com.tech.test.testbean.TestAnnotation");
        beanDefinitionRegistry.registerBeanDefinition("ceshi",rootBeanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

 测试注解

package com.tech.test.springtest;

import com.tech.test.testbean.DI;
import com.tech.test.testbean.TestAnnotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestParseAnnotation {

    public static void main(String[] args) {
        // 创建ApplicationContext,加载配置文件,实例化容器
        ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取Bean
        TestAnnotation testAnnotation = classPathXmlApplicationContext.getBean(TestAnnotation.class);

        System.out.println(testAnnotation);
    }
}

spring 详解三 IOC(spring实例化及后处理器),springBoot,spring,数据库,sql

Bean后处理器BeanPostProcessor

Bean后处理器 ,在Bean实例化之后,填充至singletonObjects之前执行,一但添加至singletonObjects意味着不能改变

 示例:为spring中的Bean执行方法添加时间,执行开始之前加入时间,执行之后加入时间,这里使用jdk动态代理做增强

package com.tech.test.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.Proxy;
import java.util.Date;

public class MyBeanProcessor implements BeanPostProcessor {

    // before 和after之间隔着InitliazeBean初始化的执行过程

      @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }


    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        Object proxyBean = Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                bean.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("方法" + method.getName() + "开始时间" + new Date());

                    // 执行目标方法
                    Object invoke = method.invoke(bean, args);

                    System.out.println("方法" + method.getName() + "结束时间" + new Date());
                    return invoke;
        });
        return proxyBean;
    }
}
<bean  class="com.tech.test.processor.MyBeanProcessor"></bean>

测试结果

package com.tech.test.springtest;

import com.tech.test.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestApplicationContext {
    public static void main(String[] args) {

        ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService =(UserService) classPathXmlApplicationContext.getBean("userService");


        userService.getUser();

    }
}

spring 详解三 IOC(spring实例化及后处理器),springBoot,spring,数据库,sql文章来源地址https://www.toymoban.com/news/detail-537926.html

到了这里,关于spring 详解三 IOC(spring实例化及后处理器)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring MVC 异常处理器

    如果不加以异常处理,错误信息肯定会抛在浏览器页面上,这样很不友好,所以必须进行异常处理。 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图: 编写controller 在index.jsp里面定义超链接

    2024年01月22日
    浏览(44)
  • 【Spring】BeanPostProcessor后置处理器

    BeanPostProcessor后置处理器是Spring提供的一个扩展点,可以在Bean初始化前后做一些事情,注意这里是bean的初始化,不是实例化,BeanPostProcessor是一个接口,里面提供了两个方法,分别为postProcessBeforeInitialization(初始化之前)和postProcessAfterInitialization(初始化之后),在方法入参

    2024年02月08日
    浏览(48)
  • Spring MVC配置全局异常处理器!!!

    为什么要使用全局异常处理器:如果不加以异常处理,错误信息肯定会抛在浏览器页面上,这样很不友好,所以必须进行异常处理。 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图: 结果展示:  

    2024年01月15日
    浏览(44)
  • spring框架_常见工厂后处理器

    ConfigurationClassPostProcessor :用于解析@ComponentScan @Bean @Import @ImportResource MapperSacnnerConfigurer :相当于Mybatis的@MapperScanner 用于解析被标注的@Mapper接口 @mapper 注解的解析:@mapper注解是mybatis提供的,用于标明一个接口,spring自然无法管理接口,要将这个接口转化为一个bean加入到beanfa

    2024年02月05日
    浏览(44)
  • Spring Boot 如何自定义异常处理器

    在Spring Boot应用程序中,异常处理是一个非常重要的方面。如果您不处理异常,应用程序可能会崩溃或出现不可预料的行为。默认情况下,Spring Boot将未捕获的异常返回给客户端。这通常不是期望的行为,因为客户端可能无法理解异常信息。在本文中,我们将介绍如何在Sprin

    2024年02月06日
    浏览(42)
  • Spring MVC文件上传及全局异常处理器

    编写controller 在index.jsp里面定义超链接 如果不加以异常处理,错误信息肯定会抛在浏览器页面上,这样很不友好,所以必须进行异常处理。 系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图: 编写c

    2024年01月18日
    浏览(48)
  • 警告:未配置spring boot 配置注解处理器

    前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 问题 我再使用@ConfigurationProperties(prefix = “redisson”)去加载配置文件中的属性的时候,发现idea有个警告 并且配置文件里面还有警告 虽然项目能够正常运行,可

    2024年01月19日
    浏览(43)
  • Spring源码学习-后置处理器,Autowired实现原理

    Autowired实现原理 populateBean 给创建好的bean实例进行普通属性的赋值 InstantiationAwareBeanPostProcessor AutowiredAnnotationBeanPostProcessor 这个就是用来完成Autowired注解能够自动装配的bean后置处理器 这个方法初始化了一个set,用来存放需要解析的自动装配注解,里面就包括Autowired,Value和Inject等

    2024年02月16日
    浏览(41)
  • Spring后置处理器BeanFactoryPostProcessor与BeanPostProcessor源码解析

    Spring有两种类型的后置处理器,分别是 BeanFactoryPostProcessor 和 BeanPostProcessor ,这里再贴出我画的 Spring 启动过程,可以看看这两种后置处理器在 Spring 启动过程中位置。 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法在 Spring 容器启动时被调用,可以对整个容器中的 BeanDefinition (

    2024年02月13日
    浏览(51)
  • Spring源码解析(八):bean后置处理器CommonAnnotationBeanPostProcessor

    Spring源码系列文章 Spring源码解析(一):环境搭建 Spring源码解析(二):bean容器的创建、默认后置处理器、扫描包路径bean Spring源码解析(三):bean容器的刷新 Spring源码解析(四):单例bean的创建流程 Spring源码解析(五):循环依赖 Spring源码解析(六):bean工厂后置处理器ConfigurationCla

    2024年02月13日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包