前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >惊呆了,spring中竟然有12种定义bean的方法

惊呆了,spring中竟然有12种定义bean的方法

作者头像
CSDN技术头条
发布于 2021-07-23 03:25:21
发布于 2021-07-23 03:25:21
1.1K00
代码可运行
举报
文章被收录于专栏:CSDN技术头条CSDN技术头条
运行总次数:0
代码可运行

前言

在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜。我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工作中的多种业务场景。

那么问题来了,你知道spring中有哪些方式可以定义bean?

我估计很多人会说出以下三种:

没错,但我想说的是以上三种方式只是开胃小菜,实际上spring的功能远比你想象中更强大。

各位看官如果不信,请继续往下看。

1. xml文件配置bean

我们先从xml配置bean开始,它是spring最早支持的方式。后来,随着springboot越来越受欢迎,该方法目前已经用得很少了,但我建议我们还是有必要了解一下。

1.1 构造器

如果你之前有在bean.xml文件中配置过bean的经历,那么对如下的配置肯定不会陌生:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="personService" class="com.sue.cache.service.test7.PersonService">
</bean>

这种方式是以前使用最多的方式,它默认使用了无参构造器创建bean。

当然我们还可以使用有参的构造器,通过<constructor-arg>标签来完成配置。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="personService" class="com.sue.cache.service.test7.PersonService">
   <constructor-arg index="0" value="susan"></constructor-arg>
   <constructor-arg index="1" ref="baseInfo"></constructor-arg>
</bean>

其中:

  • index表示下标,从0开始。
  • value表示常量值
  • ref表示引用另一个bean

1.2 setter方法

除此之外,spring还提供了另外一种思路:通过setter方法设置bean所需参数,这种方式耦合性相对较低,比有参构造器使用更为广泛。

先定义Person实体:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Data
public class Person {
    private String name;
    private int age;
}

它里面包含:成员变量name和age,getter/setter方法。

然后在bean.xml文件中配置bean时,加上<property>标签设置bean所需参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="person" class="com.sue.cache.service.test7.Person">
   <property name="name" value="susan"></constructor-arg>
   <property name="age" value="18"></constructor-arg>
</bean>

1.3 静态工厂

这种方式的关键是需要定义一个工厂类,它里面包含一个创建bean的静态方法。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class SusanBeanFactory {
    public static Person createPerson(String name, int age) {
        return new Person(name, age);
    }
}

接下来定义Person类如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Person {
    private String name;
    private int age;
}

它里面包含:成员变量name和age,getter/setter方法,无参构造器和全参构造器。

然后在bean.xml文件中配置bean时,通过factory-method参数指定静态工厂方法,同时通过<constructor-arg>设置相关参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean class="com.sue.cache.service.test7.SusanBeanFactory" factory-method="createPerson">
   <constructor-arg index="0" value="susan"></constructor-arg>
   <constructor-arg index="1" value="18"></constructor-arg>
</bean>

1.4 实例工厂方法

这种方式也需要定义一个工厂类,但里面包含非静态的创建bean的方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class SusanBeanFactory {
    public Person createPerson(String name, int age) {
        return new Person(name, age);
    }
}

Person类跟上面一样,就不多说了。

然后bean.xml文件中配置bean时,需要先配置工厂bean。然后在配置实例bean时,通过factory-bean参数指定该工厂bean的引用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="susanBeanFactory" class="com.sue.cache.service.test7.SusanBeanFactory">
</bean>
<bean factory-bean="susanBeanFactory" factory-method="createPerson">
   <constructor-arg index="0" value="susan"></constructor-arg>
   <constructor-arg index="1" value="18"></constructor-arg>
</bean>

1.5 FactoryBean

不知道大家有没有发现,上面的实例工厂方法每次都需要创建一个工厂类,不方面统一管理。

这时我们可以使用FactoryBean接口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class UserFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
        return new User();
    }

    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}

在它的getObject方法中可以实现我们自己的逻辑创建对象,并且在getObjectType方法中我们可以定义对象的类型。

然后在bean.xml文件中配置bean时,只需像普通的bean一样配置即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="userFactoryBean" class="com.sue.async.service.UserFactoryBean">
</bean>

轻松搞定,so easy。

注意:getBean("userFactoryBean");获取的是getObject方法中返回的对象。而getBean("&userFactoryBean");获取的才是真正的UserFactoryBean对象。

我们通过上面五种方式,在bean.xml文件中把bean配置好之后,spring就会自动扫描和解析相应的标签,并且帮我们创建和实例化bean,然后放入spring容器中。

虽说基于xml文件的方式配置bean,简单而且非常灵活,比较适合一些小项目。但如果遇到比较复杂的项目,则需要配置大量的bean,而且bean之间的关系错综复杂,这样久而久之会导致xml文件迅速膨胀,非常不利于bean的管理。

2. Component注解

为了解决bean太多时,xml文件过大,从而导致膨胀不好维护的问题。在spring2.5中开始支持:@Component@Repository@Service@Controller等注解定义bean。

如果你有看过这些注解的源码的话,就会惊奇得发现:其实后三种注解也是@Component

@Component系列注解的出现,给我们带来了极大的便利。我们不需要像以前那样在bean.xml文件中配置bean了,现在只用在类上加Component、Repository、Service、Controller,这四种注解中的任意一种,就能轻松完成bean的定义。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Service
public class PersonService {
    public String get() {
        return "data";
    }
}

其实,这四种注解在功能上没有特别的区别,不过在业界有个不成文的约定:

  • Controller 一般用在控制层
  • Service 一般用在业务层
  • Repository 一般用在数据层
  • Component 一般用在公共组件上

太棒了,简直一下子解放了我们的双手。

不过,需要特别注意的是,通过这种@Component扫描注解的方式定义bean的前提是:需要先配置扫描路径

目前常用的配置扫描路径的方式如下:

  1. 在applicationContext.xml文件中使用<context:component-scan>标签。例如:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<context:component-scan base-package="com.sue.cache" />
  1. 在springboot的启动类上加上@ComponentScan注解,例如:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ComponentScan(basePackages = "com.sue.cache")
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args);
    }
}
  1. 直接在SpringBootApplication注解上加,它支持ComponentScan功能:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@SpringBootApplication(scanBasePackages = "com.sue.cache")
public class Application {
    
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args);
    }
}

当然,如果你需要扫描的类跟springboot的入口类,在同一级或者子级的包下面,无需指定scanBasePackages参数,spring默认会从入口类的同一级或者子级的包去找。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@SpringBootApplication
public class Application {
    
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args);
    }
}

此外,除了上述四种@Component注解之外,springboot还增加了@RestController注解,它是一种特殊的@Controller注解,所以也是@Component注解。

@RestController还支持@ResponseBody注解的功能,即将接口响应数据的格式自动转换成json。

@Component系列注解已经让我们爱不释手了,它目前是我们日常工作中最多的定义bean的方式。

3. JavaConfig

@Component系列注解虽说使用起来非常方便,但是bean的创建过程完全交给spring容器来完成,我们没办法自己控制。

spring从3.0以后,开始支持JavaConfig的方式定义bean。它可以看做spring的配置文件,但并非真正的配置文件,我们需要通过编码java代码的方式创建bean。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
public class MyConfiguration {

    @Bean
    public Person person() {
        return new Person();
    }
}

在JavaConfig类上加@Configuration注解,相当于配置了<beans>标签。而在方法上加@Bean注解,相当于配置了<bean>标签。

此外,springboot还引入了一些列的@Conditional注解,用来控制bean的创建。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
public class MyConfiguration {

    @ConditionalOnClass(Country.class)
    @Bean
    public Person person() {
        return new Person();
    }
}

@ConditionalOnClass注解的功能是当项目中存在Country类时,才实例化Person类。换句话说就是,如果项目中不存在Country类,就不实例化Person类。

这个功能非常有用,相当于一个开关控制着Person类,只有满足一定条件才能实例化。

spring中使用比较多的Conditional还有:

  • ConditionalOnBean
  • ConditionalOnProperty
  • ConditionalOnMissingClass
  • ConditionalOnMissingBean
  • ConditionalOnWebApplication

如果你对这些功能比较感兴趣,可以看看《spring中那些让你爱不释手的代码技巧(续集)》,这是我之前写的一篇文章,里面做了更详细的介绍。

下面用一张图整体认识一下@Conditional家族:

nice,有了这些功能,我们终于可以告别麻烦的xml时代了。

4. Import注解

通过前面介绍的@Configuration和@Bean相结合的方式,我们可以通过代码定义bean。但这种方式有一定的局限性,它只能创建该类中定义的bean实例,不能创建其他类的bean实例,如果我们想创建其他类的bean实例该怎么办呢?

这时可以使用@Import注解导入。

4.1 普通类

spring4.2之后@Import注解可以实例化普通类的bean实例。例如:

先定义了Role类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Data
public class Role {
    private Long id;
    private String name;
}

接下来使用@Import注解导入Role类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Import(Role.class)
@Configuration
public class MyConfig {
}

然后在调用的地方通过@Autowired注解注入所需的bean。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/")
@RestController
public class TestController {

    @Autowired
    private Role role;

    @GetMapping("/test")
    public String test() {
        System.out.println(role);
        return "test";
    }
}

聪明的你可能会发现,我没有在任何地方定义过Role的bean,但spring却能自动创建该类的bean实例,这是为什么呢?

这也许正是@Import注解的强大之处。

此时,有些朋友可能会问:@Import注解能定义单个类的bean,但如果有多个类需要定义bean该怎么办呢?

恭喜你,这是个好问题,因为@Import注解也支持。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Import({Role.class, User.class})
@Configuration
public class MyConfig {
}

甚至,如果你想偷懒,不想写这种MyConfig类,springboot也欢迎。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Import({Role.class, User.class})
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class})
public class Application {

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(WebApplicationType.SERVLET).run(args);
    }
}

可以将@Import加到springboot的启动类上。

这样也能生效?

springboot的启动类一般都会加@SpringBootApplication注解,该注解上加了@SpringBootConfiguration注解。

而@SpringBootConfiguration注解,上面又加了@Configuration注解

所以,springboot启动类本身带有@Configuration注解的功能。

意不意外?惊不惊喜?

4.2 Configuration类

上面介绍了@Import注解导入普通类的方法,它同时也支持导入Configuration类。

先定义一个Configuration类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
public class MyConfig2 {

    @Bean
    public User user() {
        return  new User();
    }

    @Bean
    public Role role() {
        return new Role();
    }
}

然后在另外一个Configuration类中引入前面的Configuration类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Import({MyConfig2.class})
@Configuration
public class MyConfig {
}

这种方式,如果MyConfig2类已经在spring指定的扫描目录或者子目录下,则MyConfig类会显得有点多余。因为MyConfig2类本身就是一个配置类,它里面就能定义bean。

但如果MyConfig2类不在指定的spring扫描目录或者子目录下,则通过MyConfig类的导入功能,也能把MyConfig2类识别成配置类。这就有点厉害了喔。

其实下面还有更高端的玩法

swagger作为一个优秀的文档生成框架,在spring项目中越来越受欢迎。接下来,我们以swagger2为例,介绍一下它是如何导入相关类的。

众所周知,我们引入swagger相关jar包之后,只需要在springboot的启动类上加上@EnableSwagger2注解,就能开启swagger的功能。

其中@EnableSwagger2注解中导入了Swagger2DocumentationConfiguration类。

该类是一个Configuration类,它又导入了另外两个类:

  • SpringfoxWebMvcConfiguration
  • SwaggerCommonConfiguration

SpringfoxWebMvcConfiguration类又会导入新的Configuration类,并且通过@ComponentScan注解扫描了一些其他的路径。

SwaggerCommonConfiguration同样也通过@ComponentScan注解扫描了一些额外的路径。

如此一来,我们通过一个简单的@EnableSwagger2注解,就能轻松的导入swagger所需的一系列bean,并且拥有swagger的功能。

还有什么好说的,狂起点赞,简直完美。

4.3 ImportSelector

上面提到的Configuration类,它的功能非常强大。但怎么说呢,它不太适合加复杂的判断条件,根据某些条件定义这些bean,根据另外的条件定义那些bean。

那么,这种需求该怎么实现呢?

这时就可以使用ImportSelector接口了。

首先定义一个类实现ImportSelector接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class DataImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.sue.async.service.User", "com.sue.async.service.Role"};
    }
}

重写selectImports方法,在该方法中指定需要定义bean的类名,注意要包含完整路径,而非相对路径。

然后在MyConfig类上@Import导入这个类即可:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Import({DataImportSelector.class})
@Configuration
public class MyConfig {
}

朋友们是不是又发现了一个新大陆?

不过,这个注解还有更牛逼的用途。

@EnableAutoConfiguration注解中导入了AutoConfigurationImportSelector类,并且里面包含系统参数名称:spring.boot.enableautoconfiguration

AutoConfigurationImportSelector类实现了ImportSelector接口。

并且重写了selectImports方法,该方法会根据某些注解去找所有需要创建bean的类名,然后返回这些类名。其中在查找这些类名之前,先调用isEnabled方法,判断是否需要继续查找。

该方法会根据ENABLED_OVERRIDE_PROPERTY的值来作为判断条件。

而这个值就是spring.boot.enableautoconfiguration

换句话说,这里能根据系统参数控制bean是否需要被实例化,优秀。

我个人认为实现ImportSelector接口的好处主要有以下两点:

  1. 把某个功能的相关类,可以放到一起,方面管理和维护。
  2. 重写selectImports方法时,能够根据条件判断某些类是否需要被实例化,或者某个条件实例化这些bean,其他的条件实例化那些bean等。我们能够非常灵活的定制化bean的实例化。

4.4 ImportBeanDefinitionRegistrar

我们通过上面的这种方式,确实能够非常灵活的自定义bean。

但它的自定义能力,还是有限的,它没法自定义bean的名称和作用域等属性。

有需求,就有解决方案。

接下来,我们一起看看ImportBeanDefinitionRegistrar接口的神奇之处。

先定义CustomImportSelector类实现ImportBeanDefinitionRegistrar接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class CustomImportSelector implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition roleBeanDefinition = new RootBeanDefinition(Role.class);
        registry.registerBeanDefinition("role", roleBeanDefinition);

        RootBeanDefinition userBeanDefinition = new RootBeanDefinition(User.class);
        userBeanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
        registry.registerBeanDefinition("user", userBeanDefinition);
    }
}

重写registerBeanDefinitions方法,在该方法中我们可以获取BeanDefinitionRegistry对象,通过它去注册bean。不过在注册bean之前,我们先要创建BeanDefinition对象,它里面可以自定义bean的名称、作用域等很多参数。

然后在MyConfig类上导入上面的类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Import({CustomImportSelector.class})
@Configuration
public class MyConfig {
}

我们所熟悉的fegin功能,就是使用ImportBeanDefinitionRegistrar接口实现的:

具体细节就不多说了,有兴趣的朋友可以加我微信找我私聊。

5. PostProcessor

除此之外,spring还提供了专门注册bean的接口:BeanDefinitionRegistryPostProcessor

该接口的方法postProcessBeanDefinitionRegistry上有这样一段描述:

修改应用程序上下文的内部bean定义注册表标准初始化。所有常规bean定义都将被加载,但是还没有bean被实例化。这允许进一步添加在下一个后处理阶段开始之前定义bean。

如果用这个接口来定义bean,我们要做的事情就变得非常简单了。只需定义一个类实现BeanDefinitionRegistryPostProcessor接口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component
public class MyRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        RootBeanDefinition roleBeanDefinition = new RootBeanDefinition(Role.class);
        registry.registerBeanDefinition("role", roleBeanDefinition);

        RootBeanDefinition userBeanDefinition = new RootBeanDefinition(User.class);
        userBeanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
        registry.registerBeanDefinition("user", userBeanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }
}

重写postProcessBeanDefinitionRegistry方法,在该方法中能够获取BeanDefinitionRegistry对象,它负责bean的注册工作。

不过细心的朋友可能会发现,里面还多了一个postProcessBeanFactory方法,没有做任何实现。

这个方法其实是它的父接口:BeanFactoryPostProcessor里的方法。

在应用程序上下文的标准bean工厂之后修改其内部bean工厂初始化。所有bean定义都已加载,但没有bean将被实例化。这允许重写或添加属性甚至可以初始化bean。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component
public class MyPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        DefaultListableBeanFactory registry = (DefaultListableBeanFactory)beanFactory;
        RootBeanDefinition roleBeanDefinition = new RootBeanDefinition(Role.class);
        registry.registerBeanDefinition("role", roleBeanDefinition);

        RootBeanDefinition userBeanDefinition = new RootBeanDefinition(User.class);
        userBeanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
        registry.registerBeanDefinition("user", userBeanDefinition);
    }
}

既然这两个接口都能注册bean,那么他们有什么区别?

  • BeanDefinitionRegistryPostProcessor 更侧重于bean的注册
  • BeanFactoryPostProcessor 更侧重于对已经注册的bean的属性进行修改,虽然也可以注册bean。

此时,有些朋友可能会问:既然拿到BeanDefinitionRegistry对象就能注册bean,那通过BeanFactoryAware的方式是不是也能注册bean呢?

从下面这张图能够看出DefaultListableBeanFactory就实现了BeanDefinitionRegistry接口。

这样一来,我们如果能够获取DefaultListableBeanFactory对象的实例,然后调用它的注册方法,不就可以注册bean了?

说时迟那时快,定义一个类实现BeanFactoryAware接口:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component
public class BeanFactoryRegistry implements BeanFactoryAware {
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        DefaultListableBeanFactory registry = (DefaultListableBeanFactory) beanFactory;
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(User.class);
        registry.registerBeanDefinition("user", rootBeanDefinition);

        RootBeanDefinition userBeanDefinition = new RootBeanDefinition(User.class);
        userBeanDefinition.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
        registry.registerBeanDefinition("user", userBeanDefinition);
    }
}

重写setBeanFactory方法,在该方法中能够获取BeanFactory对象,它能够强制转换成DefaultListableBeanFactory对象,然后通过该对象的实例注册bean。

当你满怀喜悦的运行项目时,发现竟然报错了:

为什么会报错?

spring中bean的创建过程顺序大致如下:

BeanFactoryAware接口是在bean创建成功,并且完成依赖注入之后,在真正初始化之前才被调用的。在这个时候去注册bean意义不大,因为这个接口是给我们获取bean的,并不建议去注册bean,会引发很多问题。

此外,ApplicationContextRegistry和ApplicationListener接口也有类似的问题,我们可以用他们获取bean,但不建议用它们注册bean。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GitChat精品课 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
面试官:spring中定义bean的方法有哪些?我一口气说出了12种,把面试官整懵了。
在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜。我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工作中的多种业务场景。
苏三说技术
2021/07/08
6110
面试官:spring中定义bean的方法有哪些?我一口气说出了12种,把面试官整懵了。
17-SpringBoot自动配置-@Import详解
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到 IOC 容器中。
Devops海洋的渔夫
2022/03/23
2960
17-SpringBoot自动配置-@Import详解
实力总结四类Bean注入Spring的方式
一提到Spring,大家最先想到的是啥?是AOP和IOC的两大特性?是Spring中Bean的初始化流程?还是基于Spring的Spring Cloud全家桶呢?
阿Q说代码
2022/05/23
3560
实力总结四类Bean注入Spring的方式
Spring源码:bean的生命周期(一)
本节将正式介绍Spring源码细节,将讲解Bean生命周期。请注意,虽然我们不希望过于繁琐地理解Spring源码,但也不要认为Spring源码很简单。在本节中,我们将主要讲解Spring 5.3.10版本的源代码。如果您看到的代码与我讲解的不同,也没有关系,因为其中的原理和业务逻辑基本相同。为了更好地理解,我们将先讲解Bean的生命周期,再讲解Spring的启动原理和流程,因为启动是准备工作的一部分。
努力的小雨
2024/04/30
1580
Spring Framework 源码学习笔记(二)
测试运行时如何根据操作系统的不同来实例化不同的Bean?即如何选择性的注入Bean,这就需要用到@Conditional注解,定义选择条件需要实现Condition接口
RiemannHypothesis
2022/08/19
2670
Spring Framework 源码学习笔记(二)
SpringBoot基础(四):bean的多种加载方式
使用AnnotationConfigApplicationContext对象加载MyConfig,即使MyConfig类什么注解没有,也会被注册为bean。
Java微观世界
2025/01/21
1860
SpringBoot基础(四):bean的多种加载方式
【愚公系列】2023年10月 Java教学课程 166-SpringBoot自动配置(Enable注解原理和@Import详解)
SpringBoot中的@Enable注解是用来启用某些自动配置的功能,实际上@Enable注解是对@Import注解的封装,通过导入一个配置类来实现自动配置的功能。
愚公搬代码
2025/05/28
590
【Spring】Spring常用注解(上)
为了伟大的房产事业
2024/03/15
1220
扒一扒Bean注入到Spring的那些姿势
其实关于Bean注入Spring容器的方式网上也有很多相关文章,但是很多文章可能会存在以下常见的问题
捡田螺的小男孩
2023/02/22
4150
扒一扒Bean注入到Spring的那些姿势
逐行阅读Spring5.X源码(三) BeanDefinition的实现类详解,拔高
上回咱们讲了BeanDefinition的父接口及父接口实现类。本篇博文咱么继续讲BeanDefinition的实现类。包括AbstractBeanDefinition、RootBeanDefinition、ChildBeanDefinition、GenericBeanDefinition、AnnotateGenericBeanDefinition、ScannerGenericBeanDefinition。
源码之路
2020/09/04
1.8K0
逐行阅读Spring5.X源码(三) BeanDefinition的实现类详解,拔高
【小家Spring】Spring IoC容器中核心定义之------BeanDefinition深入分析(RootBeanDefinition、ChildBeanDefinition...)
在前面分析Spring IoC容器的时候,贯穿全文的一个概念:Bean定义信息。它是Spring容器的一个核心概念,那么本文就深入分析一下BeanDefinition这个接口(类)。
YourBatman
2019/09/03
7.5K1
【小家Spring】Spring IoC容器中核心定义之------BeanDefinition深入分析(RootBeanDefinition、ChildBeanDefinition...)
Spring 源码第四弹!深入理解 BeanDefinition
在 Spring 容器中,我们广泛使用的是一个一个的 Bean,BeanDefinition 从名字上就可以看出是关于 Bean 的定义。
江南一点雨
2020/07/07
4810
Spring 源码第四弹!深入理解 BeanDefinition
Spring学习笔记
1.Spring是一个开源框架,主要优势之一是其分层架构,分层架构允许使用者选择使用哪一个组件. Spring的核心是IOC(控制反转)和AOP(面向切面)。 2.IOC:创建类的对象的时候,使用ioc实现对象创建,通过配置文件方式创建对象。 底层原理技术:xml配置文件;dom4j解析xml文件;工厂模式;反射   AOP:不通过修改源代码方式增强类里面的方法。 3.spring框架需要的包:beans;core;context;SpEL;commons-logging-1.2; log4j-1.2.16; 4.配置文件:bean.xml   放到src下。   约束内容:
曼路
2018/10/18
3700
Spring学习笔记
深入探索Spring的Bean注入:四种方式解析与循环依赖探讨
本博客将深入探讨Spring中Bean的注入方式以及循环依赖的问题。我们将逐一介绍XML方式、注解方式(@Configuration + @Bean、@Import)、FactoryBean以及BeanDefinitionRegistryPostProcessor,通过实战演示向读者展示如何将Bean成功注入Spring容器。
猫头虎
2024/04/08
1.3K1
深入探索Spring的Bean注入:四种方式解析与循环依赖探讨
这些 Spring 面试加分项,必看!
最近在带大家做新项目,欢迎参与 大家好,我是鱼皮。 前言 我们一说到spring,可能第一个想到的是 IOC(控制反转) 和 AOP(面向切面编程)。 没错,它们是 spring 的基石,得益于它们的优秀设计,使得 spring 能够从众多优秀框架中脱颖而出。 除此之外,我们在使用 spring 的过程中,有没有发现它的扩展能力非常强。由于这个优势的存在,让 spring 拥有强大的包容能力,让很多第三方应用能够轻松投入 spring 的怀抱。比如:rocketmq、mybatis、redis等。 今天
程序员鱼皮
2023/03/29
2350
这些 Spring 面试加分项,必看!
被隔离了,聊一聊春(Spring)的生命周期
今天我们来分享一下Spring Bean的生命周期,Spring Bean的生命周期对于我们掌握Spring来说是很关键的,理解了Spring的生命周期,那么我们在开发的时候才能更好的利用Spring的功能,从而达到我们的目的!
小四的技术之旅
2022/07/26
3770
被隔离了,聊一聊春(Spring)的生命周期
Spring 学习笔记(2) Spring Bean
IoC 容器是 Spring 的核心,Spring 通过 IoC 容器来管理对象的实例化和初始化(这些对象就是 Spring Bean),以及对象从创建到销毁的整个生命周期。也就是管理对象和依赖,以及依赖的注入等等。
归思君
2023/10/16
2180
Spring 学习笔记(2) Spring Bean
springboot自动装配原理简书_万能轧机的装配原理
学习SpringBoot,绝对避不开自动装配这个概念,这也是SpringBoot的关键之一
全栈程序员站长
2022/09/23
5940
springboot自动装配原理简书_万能轧机的装配原理
SpringBoot中注册Bean的10种方式总结
在Spring Boot应用中,Bean是构成应用的核心组件。Spring容器负责管理这些Bean,包括它们的创建、配置、组装、管理和销毁。在Spring Boot中,有多种方式可以注册Bean,让Spring容器能够管理它们。本文将详细介绍这些不同的注册方式,并给出相应的示例代码和适用场景。
公众号:码到三十五
2024/08/11
1.5K0
【Spring注解驱动开发】在@Import中使用ImportBeanDefinitionRegistrar向容器中注册bean
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
冰河
2020/10/29
4700
相关推荐
面试官:spring中定义bean的方法有哪些?我一口气说出了12种,把面试官整懵了。
更多 >
LV.1
这个人很懒,什么都没有留下~
目录
  • 前言
  • 1. xml文件配置bean
    • 1.1 构造器
    • 1.2 setter方法
    • 1.3 静态工厂
    • 1.4 实例工厂方法
    • 1.5 FactoryBean
  • 2. Component注解
  • 3. JavaConfig
  • 4. Import注解
    • 4.1 普通类
    • 4.2 Configuration类
    • 4.3 ImportSelector
    • 4.4 ImportBeanDefinitionRegistrar
  • 5. PostProcessor
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档