Spring 创建Bean的6种方式

前言

本文讲解了在Spring 应用中创建Bean的多种方式,包括自动创建,以及手动创建注入方式,实际开发中可以根据业务场景选择合适的方案。

方式1:

使用Spring XML方式配置,该方式用于在纯Spring 应用中,适用于简单的小应用,当应用变得复杂,将会导致Bean管理很麻烦

<bean id="xxxx"  class="xxxx.xxxx"/>

方式2:

使用@Component,@Service,@Controler,@Repository注解

这几个注解都是同样的功能,被注解的类将会被Spring 容器创建单例对象。

@Component : 侧重于通用的Bean类

@Service:标识该类用于业务逻辑

@Controler:标识该类为Spring MVC的控制器类

@Repository: 标识该类是一个实体类,只有属性和Setter,Getter

@Component
public class User{
}

当用于Spring Boot应用时,被注解的类必须在启动类的根路径或者子路径下,否则不会生效。

如果不在,可以使用@ComponentScan标注扫描的路径。

spring xml 也有相关的标签<component-scan />

@ComponentScan(value={"com.microblog.blog","com.microblog.common"})
public class MicroblogBlogApplication {
    public static void main(String args[]){
        SpringApplication.run(MicroblogBlogApplication.class,args);
    }
}

方式3:

使用@Bean注解,这种方式用在Spring Boot 应用中。

@Configuration 标识这是一个Spring Boot 配置类,其将会扫描该类中是否存在@Bean 注解的方法,比如如下代码,将会创建User对象并放入容器中。

@ConditionalOnBean 用于判断存在某个Bean时才会创建User Bean.

这里创建的Bean名称默认为方法的名称user。也可以@Bean("xxxx")定义。

@Configuration
public class UserConfiguration{

      @Bean    @ConditionalOnBean(Location.class)
      public User user(){
           return new User();
      }

}    

Spring boot 还为我们提供了更多类似的注解。

也和方式2一样,也会存在扫描路径的问题,除了以上的解决方式,还有使用Spring boot starter 的解决方式

在resources下创建如下文件。META-INF/spring.factories.

Spring Boot 在启动的时候将会扫描该文件,从何获取到配置类UserConfiguration。

spring.factories.

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.log.config.UserConfiguration

如果不成功,请引入该依赖

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>    

这个方式也是创建SpringBoot-starter的方式。

方式4:

使用注解@Import,也会创建对象并注入容器中

@Import(User.class)
public class MicroblogUserWebApplication {
    public static void main(String args[]) {
        SpringApplication.run(MicroblogUserWebApplication.class, args);
    }
}

方式5:

使用ImportSelector或者ImportBeanDefinitionRegistrar接口,配合@Import实现。

在使用一些Spring Boot第三方组件时,经常会看到@EnableXXX来使能相关的服务,这里以一个例子来实现。

创建测试类

@Slf4j
public class House {

    public void run(){

        log.info("House  run ....");
    }
}

@Slf4j
public class User {

    public void run(){

        log.info("User  run ....");

    }

}

@Slf4j
public class Student {

    public void run(){

        log.info("Student  run ....");

    }

}

实现ImportSelector接口

selectImports方法的返回值为需要创建Bean的类名称。这里创建User类。

@Slf4j
public class MyImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {

        log.info("MyImportSelector selectImports ...");
        return new String[]{
            User.class.getName()};
    }
}

实现ImportBeanDefinitionRegistrar接口

beanDefinitionRegistry.registerBeanDefinition用于设置需要创建Bean的类名称。这里创建House类。

@Slf4j
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {

        log.info("MyImportBeanDefinitionRegistrar  registerBeanDefinitions .....");
        BeanDefinition beanDefinition =  new RootBeanDefinition(House.class.getName());
        beanDefinitionRegistry.registerBeanDefinition(House.class.getName(),beanDefinition);
    }
}

创建一个配置类

这里创建Student类。

@Configuration
public class ImportAutoconfiguration {

    @Bean
    public Student student(){
        return new Student();
    }
}

创建EnableImportSelector注解

EnableImportSelector注解上使用@Import,引入以上的三个类。

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
@Import({MyImportSelector.class,ImportAutoconfiguration.class,MyImportBeanDefinitionRegistrar.class})
public @interface EnableImportSelector {

    String value();

}

测试

@EnableImportSelector(value = "xxx")
@SpringBootApplication
public class ImportDemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context =  SpringApplication.run(ImportDemoApplication.class, args);

        User user =  context.getBean(User.class);
        user.run();

        Student student =  context.getBean(Student.class);
        student.run();

        House house =  context.getBean(House.class);
        house.run();

    }

}

输出,可以看到,三个类User Student House都创建成功,都可从Spring 容器中获取到。

2019-06-20 17:53:39.528  INFO 27255 --- [           main] com.springboot.importselector.pojo.User  : User  run ....
2019-06-20 17:53:39.530  INFO 27255 --- [           main] c.s.importselector.pojo.Student          : Student  run ....
2019-06-20 17:53:39.531  INFO 27255 --- [           main] c.springboot.importselector.pojo.House   : House  run ....

方式6

手动注入Bean容器,有些场景下需要代码动态注入,以上方式都不适用。这时就需要创建 对象手动注入。

通过DefaultListableBeanFactory注入。

registerSingleton(String beanName,Object object);

这里手动使用new创建了一个Location对象。并注入容器中。

@Componentpublic class LocationRegister implements BeanFactoryAware {

    @Override    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {        DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory)beanFactory;        Location location = new Location();        listableBeanFactory.registerSingleton("location1",location);    }}

可以看以下它的继承体系

DefaultListableBeanFactory 是ConfigurableListableBeanFactory的实现类。是对BeanFactory功能的扩展。

测试代码和以上一样

Location location =  context.getBean(Location.class);
location.run();

本文的相关代码位于 实例代码 测试类

完结。

===========

原文地址:https://www.cnblogs.com/lgjlife/p/11060570.html

时间: 2024-10-31 14:04:33

Spring 创建Bean的6种方式的相关文章

spring创建bean的三种方式

1.使用构造器创建bean 1.1.使用无参构造器创建 package com.ly.spring; public class Person { private String name; public void say(String name) { System.out.println("你好,我叫"+name); } } <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&

(001)spring容器创建bean的两种方式

简单记录一下spring容器创建.装配.管理bean 1.使用@Configuration.@Bean的注解组合创建bean 可以用两种方法获取bean,根据类名或者创建bean的方法名,如果不指定bean的名字,默认bean的名字是该方法名. pom.xml文件如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.

Spring笔记——4.创建Bean的三种方式

Spring支持使用如下三种方法创建Bean: 调用构造器创建Bean 调用静态工厂方法创建Bean 调用实例工厂方法创建Bean 构造器 这是最常见的,框架底层调用bean的无参数构造器.这种情况下,class助兴是必需的.之前写的都是这种方式. 静态工厂方法创建Bean class也必须指定,但不是指定实现类,而是静态工厂类,这个工厂会创建bean实例.另外还需要factory-method指定用哪个方法创建bean实例,返回值即为实例. 接口与实现类如下: public interface

spring 装配bean的三种方式

这段时间在学习Spring,依赖注入DI和面向切面编程AOP是Spring框架最核心的部分.这次主要是总结依赖注入的bean的装配方式. 什么是依赖注入呢?也可以称为控制反转,简单的来说,一般完成稍微复杂的业务逻辑,可能需要多个类,会出现有些类要引用其他类的实例,也可以称为依赖其他类.传统的方法就是直接引用那个类对象作为自己的一个属性,但如果我们每次创建这个类的对象时,都会创建依赖的类的对象,还有如果那个类将来可能不用了,还需要到这个类去删除这个对象,那破坏了代码的复用性和导致高度耦合! 依赖注

Spring定义Bean的两种方式:和@Bean

前言:    Spring中最重要的概念IOC和AOP,实际围绕的就是Bean的生成与使用. 什么叫做Bean呢?我们可以理解成对象,每一个你想交给Spring去托管的对象都可以称之为Bean. 今天通过Spring官方文档来了解下,如何生成bean,如何使用呢? 1.通过XML的方式来生成一个bean    最简单也是最原始的一种方式,通过XML来定义一个bean,我们来看下其过程 1)创建entity,命名为Student @Data@AllArgsConstructor@NoArgsCon

Spring实例化bean的三种方式

在面向对象编程的过程中,要想调用某个类的成员方法,首先要实例化该类的成员变量. 在Spring 中,实例化Bean有三种方式: 1.构造器实例化:2.静态工厂方式实例化:3.实例化工厂方式实例化 构造器实例化:Spring容器通过Bean对应的类中默认的构造器函数实例化Bean. 1-1.创建一个实体类 Person1 package com.mengma.instance.constructor; public class Person1 { } 1-2.创建Spring配置文件,在 com.

Spring 实例化bean的三种方式

第一种方法:直接配置Bean Xml代码   <bena id="所需要实例化的一个实例名称" class="包名.类名"/> 例如: 配置文件中的bean.XML代码: Xml代码   <bean id="userA" class="com.test.User"/> Java代码   package com.test public class User{ public void test(){ Sys

Spring 实例化Bean的两种方式

使用Spring管理Bean也称依赖注入( Dependency Injection, DI ),通过这种方式将Bean的控制权交给Spring 在使用Spring实例化一个对象时,无论类是否有参数都会默认调用对象类的无参构造,对于有参数的情况,Spring有两种方式可以带参实例化 示例类 Shape public class Shape { private Integer width; private Integer height; public Shape() { System.out.pr

spring装配bean有几种方式?

一 前言 在XML中进行显式配置. 在Java中进行显式配置. 隐式的bean发现机制和自动装配 关于xml配置不会在本篇说明,有兴趣的读者可以自行了解学习: 知识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;) 二 自动装配bean 自动装配Bean主要通过如下两个方式实现自动装备bean 组件扫描(component scanning):Spring会自动扫描发现上下文中所创建的bean:对应