SpringBoot-容器功能

SpringBoot-容器功能

1.Spring 注入组件的注解

1.@Component、@Controller、 @Service、@Repository

说明: 这些在 Spring 中的传统注解仍然有效,通过这些注解可以给容器注入组件

2.案例演示

1.创建src\main\java\com\llp\bean\A.java

@Repository
public class A {
}

2.修改MainApp.java主启动类

@SpringBootApplication(scanBasePackages = {"com"})
public class MainApp {

    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);
    	//演示spring中传统的注解依然可以使用@Controller @Service @Repository
        A bean = ioc.getBean(A.class);
        //com.llp.bean.A@6c17c0f8
        System.out.println(bean);
    }
}

A类被@Repository修饰,可以看到A被注入到了Spring的ioc容器中,而默认的以类名首字母小写的方式作为bean的id

image-20220728225711741

image-20220728225525910

2.@Configuration

1.应用实例

● @Configuration 应用实例需求

演示在 SpringBoot, 如何通过@Configuration 创建配置类来注入组件

● 回顾传统方式如何通过配置文件注入组件

1.创建src\main\java\com\llp\bean\Monster.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Monster {
    private Integer id;
    private String name;
    private Integer age;
    private String skill;
}

2.创建src\main\resources\beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="monster03" class="com.llp.bean.Monster">
      <property name="id" value="100"/>
      <property name="name" value="孙悟空"/>
      <property name="age" value="1000"/>
      <property name="skill" value="刷光棍"/>
   </bean>
</beans>

3.修改主启动类

@SpringBootApplication(scanBasePackages = {"com"})
public class MainApp {

    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        Monster monster03 = ac.getBean("monster03", Monster.class);
        //Monster(id=100, name=孙悟空, age=1000, skill=刷光棍)
        System.out.println(monster03);
    }
}

SpringBoot是支持传统的方式去获取bean对象的

image-20220728230729495

● 使用 SpringBoot 的@Configuration 添加/注入组件

1.创建src\main\java\com\llp\config\BeanConfig.java

@Configuration
public class BeanConfig {

    /**
     * 1. @Bean : 给容器添加组件, 就是Monster bean
     * 2. monster01() : 默认 你的方法名monster01 作为Bean的名字/id
     * 3. Monster : 注入类型, 注入bean的类型是Monster
     * 4. new Monster(200,"库里林",200,"铁头功") 注入到容器中具体的Bean
     * 5. @Bean(name = "monster_nmw") : 在配置、注入Bean指定名字
     * 6. 默认是单例注入
     * 7. 通过 @Scope("prototype")  可以每次返回新的对象,就多例.
     */
    //@Bean(name = "monster_nmw")
    @Bean
    //@Scope("prototype")
    public Monster monster01(){
        return new Monster(200,"库里林",200,"铁头功");
    }
}

2.修改主启动类,进行测试

@SpringBootApplication(scanBasePackages = {"com"})
public class MainApp {

    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);
        Monster monster01 = ioc.getBean("monster01", Monster.class);
        //Monster(id=200, name=库里林, age=200, skill=铁头功)
        System.out.println(monster01);
    }
}

image-20220728231440370

debug查看ioc容器

image-20220728231732844

beanDefinitionMap, 只是存放了 bean 定义信息, 真正存放 Bean 实例的在 singleonObjectis 的 Map 中, 对于非单例,是每次动态反射生成的实例

image-20220728231815481

2.@Configuration注意事项和细节

  1. 配置类本身也是组件, 因此也可以获取, 测试 修改 MainApp.java
  2. SpringBoot2 新增特性: proxyBeanMethods 指定 Full 模式 和 Lite 模式

(1)修改src\main\java\com\llp\config\BeanConfig.java 设置proxyBeanMethods = true(默认为true)

/**
 * 1. proxyBeanMethods:代理bean的方法
 * (1) Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的, 是代理方式】
 * (2) Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的, 是非代理方式】
 * (3) 特别说明: proxyBeanMethods 是在 调用@Bean方法 才生效,因此,需要先获取BeanConfig 组件,再调用方法
 * 而不是直接通过 SpringBoot 主程序得到的容器来获取bean, 注意观察直接通过ioc.getBean() 获取Bean, proxyBeanMethods 值并没有生效
 * (4) 如何选择: 组件依赖必须使用Full模式默认。如果不需要组件依赖使用 Lite模式
 * (5) Lite模式 也称为轻量级模式,因为不检测依赖关系,运行速度快
 */
@Configuration(proxyBeanMethods = true)
public class BeanConfig {

    /**
     * 1. @Bean : 给容器添加组件, 就是Monster bean
     * 2. monster01() : 默认 你的方法名monster01 作为Bean的名字/id
     * 3. Monster : 注入类型, 注入bean的类型是Monster
     * 4. new Monster(200,"库里林",200,"铁头功") 注入到容器中具体的Be
     * 5. @Bean(name = "monster_nmw") : 在配置、注入Bean指定名字
     * 6. 默认是单例注入
     * 7. 通过 @Scope("prototype")  可以每次返回新的对象,就多例.
     */
    //@Bean(name = "monster_nmw")
    @Bean
    //@Scope("prototype")
    public Monster monster01(){
        return new Monster(200,"库里林",200,"铁头功");
    }
}

修改主程序进行测试

@SpringBootApplication(scanBasePackages = {"com"})
public class MainApp {

    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);
        BeanConfig bean = ioc.getBean(BeanConfig.class);
        Monster monster01 = bean.monster01();
        Monster monster02 = bean.monster01();
        //monster01 ---  1533783975
        System.out.println("monster01 ---  " + monster01.hashCode());
        //monster02 ---  1533783975
        System.out.println("monster02 ---  " + monster02.hashCode());
    }
}

Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的, 是代理方式】

image-20220728232421518

(2)修改src\main\java\com\llp\config\BeanConfig.java 设置proxyBeanMethods = fasle

/**
 * 1. proxyBeanMethods:代理bean的方法
 * (1) Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的, 是代理方式】
 * (2) Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的, 是非代理方式】
 * (3) 特别说明: proxyBeanMethods 是在 调用@Bean方法 才生效,因此,需要先获取BeanConfig 组件,再调用方法
 * 而不是直接通过 SpringBoot 主程序得到的容器来获取bean, 注意观察直接通过ioc.getBean() 获取Bean, proxyBeanMethods 值并没有生效
 * (4) 如何选择: 组件依赖必须使用Full模式默认。如果不需要组件依赖使用 Lite模式
 * (5) Lite模式 也称为轻量级模式,因为不检测依赖关系,运行速度快
 */
@Configuration(proxyBeanMethods = false)
public class BeanConfig {

    /**
     * 1. @Bean : 给容器添加组件, 就是Monster bean
     * 2. monster01() : 默认 你的方法名monster01 作为Bean的名字/id
     * 3. Monster : 注入类型, 注入bean的类型是Monster
     * 4. new Monster(200,"库里林",200,"铁头功") 注入到容器中具体的Be
     * 5. @Bean(name = "monster_nmw") : 在配置、注入Bean指定名字
     * 6. 默认是单例注入
     * 7. 通过 @Scope("prototype")  可以每次返回新的对象,就多例.
     */
    //@Bean(name = "monster_nmw")
    @Bean
    //@Scope("prototype")
    public Monster monster01(){
        return new Monster(300,"库里林",200,"铁头功");
    }
}

这里要注意一个坑,在前面我们使用lombok的@Data注解会重新hashCode方法如下图,这样会导致一个问题,只要我们对象属性的值一样那么计算出来的hashCode值就是一样的,因此要验证(lite模式)轻量级模式就需要去修改Monster.java不要使用lombok @Data注解的方式

image-20220728235333224

image-20220728235235547

  1. 配置类可以有多个, 就和 Spring 可以有多个 ioc 配置文件是一个道理.

(1)创建src\main\java\com\llp\config\BeanConfig2.java

@Configuration
public class BeanConfig2 {

    @Bean
    public Monster monster02() {
        return new Monster(800,"蚂蚁精",80,"吃小昆虫");
    }
}

(2)修改主启动类测试

@SpringBootApplication(scanBasePackages = {"com"})
public class MainApp {

    public static void main(String[] args) {
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);
        Monster monster02 = ioc.getBean("monster02", Monster.class);
        //Monster(id=800, name=蚂蚁精, age=80, skill=吃小昆虫)
        System.out.println(monster02);
    }
}

3.@Import

1.应用实例

演示在 SpringBoot, 如何通过 @Import 来注入组件

1.创建src\main\java\com\llp\bean\Cat.java和src\main\java\com\llp\bean\Dog.java

public class Cat {
}
public class Dog {
}

2.创建src\main\java\com\llp\config\BeanConfig3.java,采用@Import({Dog.class, Cat.class})的方式注入bean到ioc容器中

/**
 * 1. @Import 代码 可以看到,可以指定 class的数组, 可以注入指定类型的Bean
 * public @interface Import {
 *
 * 	 	Class<?>[] value()}
 *
 * 2. 通过@Import 方式注入了组件, 默认组件名字/id就是对应类型的全类名
 */
@Import({Dog.class, Cat.class})
@Configuration
public class BeanConfig3 {
}

3.运行主程序,查看ioc容器单例池

image-20220729223955258

4.@Conditional

1.@Conditional 介绍

  1. 条件装配:满足 Conditional 指定的条件,则进行组件注入
  2. @Conditional 是一个根注解,下面有很多扩展注解

image-20220729224434961

3.@Conditional扩展注解应用场景

image-20220729224738586

2.应用实例

  1. 要求: 演示在 SpringBoot, 如何通过 @ConditionalOnBean 来注入组件
  2. 只有在容器中有 name = cat007组件时,才注入 dog01, 代码如下
@Bean(name = "cat007")
public Cat cat01(){
    return new Cat();
}

/**
 * 1. @ConditionalOnBean(name = "cat007") 表示
 * 2. 当容器中有一个Bean , 名字是cat007 (类型不做约束), 就注入dog01这个Dog bean
 * 3. 如果没有 名字是cat007 的Bean 就不注入dog01这个Dog bean
 * 4. @ConditionalOnMissingBean(name = "cat007") 表示在容器中,
 * 没有 名字/id 为 cat007 才注入dog01这个Bean
 * 5. @ConditionalOnBean(name = "cat007") 也可以放在配置类
 * 表示对该配置类的所有要注入的组件,都进行条件约束.
 */
@Bean
@ConditionalOnBean(name = "cat007")
public Dog dog01(){
    return new Dog();
}

image-20220729231628468

image-20220729231751011

5.@ImportResource

1.作用

原生配置文件引入, 也就是可以直接导入 Spring 传统的 beans.xml ,可以认为是 SpringBoot 对 Spring 容器文件的兼容.

不使用@ImportResource引入,从ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args); ioc中是获取不到bean的

image-20220729232414148

image-20220729232353816

2.@ImportResource 应用实例

  1. 需求: 将 beans.xml 导入到 BeanConfig.java 配置类, 并测试是否可以获得 beans.xml 注入/配置的组件

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="monster03" class="com.llp.bean.Monster">
      <property name="id" value="100"/>
      <property name="name" value="孙悟空"/>
      <property name="age" value="1000"/>
      <property name="skill" value="刷光棍"/>
   </bean>
</beans>

beans02.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置了Monster bean-->
    <bean id="monster04" class="com.llp.bean.Monster">
        <property name="name" value="狐狸精"></property>
        <property name="age" value="9000"></property>
        <property name="skill" value="美人计"></property>
        <property name="id" value="2000"></property>
    </bean>
</beans>
  1. 创建新的 BeanConfig4.java来测试, 使用@ImportResource 导入 beans.xml、beans02.xml
/**
 * @Retention(RetentionPolicy.RUNTIME)
 * @Target({ElementType.TYPE})
 * @Documented
 * public @interface ImportResource {
 *     @AliasFor("locations")
 *     String[] value() default {};
 *
 *     @AliasFor("value")
 *     String[] locations() default {};
 *
 *     Class<? extends BeanDefinitionReader> reader() default BeanDefinitionReader.class;
 * }
 */
@Configuration
@ImportResource(locations = {"classpath:beans.xml","classpath:beans02.xml"})
public class BeanConfig4 {

}

3.运行主启动类,进行测试

image-20220729232938593

6.配置绑定

1.作用

一句话:使用 Java 读取到 SpringBoot 核心配置文件 application.properties 的内容, 并且把它封装到 JavaBean 中

2.应用实例

  1. 需求: 将 application.properties 指定的 k-v 和 JavaBean 绑定

在application.properties文件中加入

furn01.id=100
furn01.name=悟空
furn01.price=0.02

创建src\main\java\com\llp\bean\Furn.java

这里javaBean需要提供get和set方法,在容器启动时会利用反射调用set方法进行赋值,在获取bean进行序列化时会调用get方法

@Data
@Component
@ConfigurationProperties(prefix = "furn01")
public class Furn {
    private Integer id;
    private String name;
    private Double price;
}

修改HelloController.java

@RestController
public class HelloController {

    @Autowired
    private Furn furn;

    @RequestMapping("/hello")
    public String hello(){
        return "hello SpringBoot";
    }

    @RequestMapping("/furn")
    public Furn furn(){
        System.out.println(furn);
        return furn;
    }
}

启动容器访问测试

image-20220730083748167

3.注意事项和细节

  1. 如果 application.properties 有中文, 需要转成 unicode 编码写入, 否则出现乱码;也可以设置idea工具的编码格式

  1. 使用 @ConfigurationProperties(prefix = “furn01”) 会提示如下信息, 但是不会影响使用

image-20220730084406208

  1. 解决 @ConfigurationProperties(prefix = “furn01”) 提示信息, 在 pom.xml 增加依赖, 即可

​ 4.配置绑定还可以在配置类中添加 @EnableConfigurationProperties({Furn.class})配置如下:

@Data
//@Component
@ConfigurationProperties(prefix = "furn01")
public class Furn {
    private Integer id;
    private String name;
    private Double price;
}
@Configuration
@EnableConfigurationProperties({Furn.class})
public class BeanConfig5 {

}

重启测试,发现也是可以的

image-20220730084807645

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: idea-springboot-projectes是指使用IDEA开发工具构建Spring Boot项目的过程。Spring Boot是一个流行的开源框架,可以帮助Java开发者快速构建高效的微服务应用。IDEA则是一个以Java为基础的集成开发环境,可以提供代码编辑、调试、测试和部署等功能。 在构建Spring Boot项目时,IDEA可以通过自带的Spring Initializr工具或者通过手动配置的方式来进行。Spring Initializr可以自动生成项目基础框架,包括依赖库、项目结构、POM文件等。而手动配置则需要开发者自行添加所需要的依赖库和配置文件。 在项目开发过程中,IDEA可以提供强大的代码提示和自动补全功能,包括快捷键、代码重构、调试等。此外,IDEA还支持各种测试框架和部署方式,方便开发者快速进行测试和部署。 总的来说,使用IDEA开发Spring Boot项目可以提高开发效率和代码质量,并且可以使用各种插件和扩展来增强开发体验。这是一个非常流行的Java开发模式,适用于各种类型的应用程序和系统。 ### 回答2: Idea-SpringBoot-Project是一个使用了Spring Boot框架的项目,有助于Java开发者轻松构建Web应用程序。Spring Boot是一个流行的Java框架,它可以帮助开发者更快地构建更好的应用程序。使用Idea-SpringBoot-Project,开发者可以轻松创建具有高可用性和可扩展性的Java Web应用程序。 Idea-SpringBoot-Project引入了许多方便的功能,如Spring容器管理、数据访问和Web MVC框架等。通过使用Spring Boot,开发者可以在不需要手动配置的情况下快速构建应用程序。而使用Idea作为开发工具,则能帮助开发者更快地编写代码和进行调试。这个项目不仅可以在Windows和Linux平台上运行,还与许多其他大型Java库和框架兼容,如Spring Security和Hibernate等。 总之,Idea-SpringBoot-Project帮助开发者将更多的时间专注于应用程序逻辑和功能,而不是花费时间和精力去手动配置。通过这个项目,开发者可以构建出高性能、高度可用性和可扩展性的Java应用程序。 ### 回答3: idea-springboot-projectes是针对Spring Boot框架的项目管理功能的开发工具集成环境。它提供了一种方便快捷的方式来创建、维护和调试Spring Boot项目。 idea-springboot-projectes使开发人员能够在一个单一的界面中,管理不同的Spring Boot项目,包括应用程序、库和插件。它自动生成项目结构,提供依赖管理,支持代码重构、调试和测试等功能,同时也能够整合其他常用开发工具如Maven、Gradle等,进一步提升开发效率。 通过idea-springboot-projectes,开发人员可以快速创建Spring Boot应用程序。一旦项目创建完成,可以通过IDEA的自动配置机制,无需编写大量的代码即可完成基础设施的搭建和配置。同时,IDEA也提供了许多Spring Boot Starter库,这些库包含了大量常用的功能和组件,帮助开发人员轻松实现各种业务需求。 总之,idea-springboot-projectes是一款非常实用的开发工具,为Spring Boot开发提供了强大的项目管理和开发支持,同时提高了开发效率和代码质量,使得开发人员能够更专注于业务代码的编写。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值