SpringBoot的IOC容器bean查看、@SpringBootApplication、@Configuration、@Import、@ImportResource注解

常用的注解有@Service:表示业务逻辑组件,@Repository:表示数据库组件

1. 查看IOC容器bean的name、@SpringBootApplication使用介绍

查看IOC容器bean的name:

  1. SpringApplication.run会返回IOC容器ConfigurableApplicationContext
  2. 然后通过ConfigurableApplicationContext.getBeanDefinitionNames返回IOC容器所有bean的name

@SpringBootApplication使用介绍:

  • @SpringBootApplication的参数scanBasePackages会使默认的目录不被扫描,扫描新的目录
  • @ComponentScan会使@SpringBootApplication的目录不被扫描,扫描新的目录
  • @SpringBootApplication等同于@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan

如下所示:

package com.hh.springbootTest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

// scanBasePackages会使默认的目录不被扫描,扫描新的目录
@SpringBootApplication(scanBasePackages = "com.hh.springbootTest")

// 会使@SpringBootApplication的目录不被扫描,扫描新的目录
@ComponentScan("com.hh")

// @SpringBootApplication等同于@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan("com.hh.springbootTest")
public class MyApplication {

    public static void main(String[] args) {

        // 返回IOC容器
        ConfigurableApplicationContext applicationContext =
                SpringApplication.run(MyApplication.class, args);

        // 查看IOC容器中的Bean对应的name
        String[] beanNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }

        int beanCount = applicationContext.getBeanDefinitionCount();
    }
}

运行程序,查看的所有bean的name如下:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
......省略部分......
viewResolver                // 进行文件上传的
......省略部分......
characterEncodingFilter     // 进行字符编码的
......省略部分......
multipartResolver
spring.servlet.multipart-org.springframework.boot.autoconfigure.web.servlet.MultipartProperties
org.springframework.aop.config.internalAutoProxyCreator

2. 自定义SpringApplication

参数设置的优先级比application.properties低

方式一:通过new一个类得到对象的方式

package com.hh.springboottest;

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootTestApplication {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class);

        // 进行各种参数设置
        springApplication.setBannerMode(Banner.Mode.OFF);

        springApplication.run(args);
    }

}

方式二:Builder方式。通过FluentAPI进行设置

package com.hh.springboottest;

import org.springframework.boot.Banner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class SpringBootTestApplication {

    public static void main(String[] args) {
        
        new SpringApplicationBuilder()
                .main(SpringBootTestApplication.class)
                .sources(SpringBootTestApplication.class)
                .bannerMode(Banner.Mode.OFF)
                .run(args);

    }

}

3. @Configuration注解

创建User类,如下所示:

package com.hh.springbootTest.myBean;

public class User {

    private String name;

    public User(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "User{" + "name='" + name + "'}";
    }
}

@Configuration注解说明:

  • 声明修饰的类是一个配置类,配置类也是IOC容器的一个组件
  • proxyBeanMethods默认为true(Full),表示如果IOC容器有要获取的组件,则直接从IOC容器取, 实现单例功能。一般用于创建的对象之间有依赖
  • proxyBeanMethods为false(Lite)则直接new一个,大部分场景使用,可以加速IOC容器启动
  • 也可以在

@Bean注解说明:

  • 表示向IOC容器添加name为userName1(默认是方法名),类型为User,值为User{name=‘user1’}的组件
  • 也可以在方法上使用@Scope。如果类上定义了proxyBeanMethods为false,则@Scope失效

示例程序如下:

package com.hh.springbootTest.myConfig;

import com.hh.springbootTest.myBean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// proxyBeanMethods:表示代理bean的方法
//      默认为true(Full),表示如果IOC容器有要获取的组件,则直接从IOC容器取, 实现单例功能。一般用于创建的对象之间有依赖
//      false(Lite)则直接new一个,大部分场景使用,可以加速IOC容器启动
@Configuration(proxyBeanMethods = true)  // 声明这是一个配置类,等同于一个配置文件。配置类本身也是组件
public class MyConfig {

    @Scope("singleton")     // 多实例对象prototype。默认是singleton
    // 向IOC容器添加name为userName1(默认是方法名),类型为User,值为User{name='user1'}的组件
    @Bean("userName1")
    public User userName1() {
        return new User("user1");
    }

}

可以在主程序中,从IOC容器获取Bean对象,获取的方式有很多种,如下所示:

package com.hh.springbootTest;

import com.hh.springbootTest.myBean.User;
import com.hh.springbootTest.myConfig.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {

        // 返回IOC容器
        ConfigurableApplicationContext applicationContext =
                SpringApplication.run(MyApplication.class, args);

        // 通过IOC容器的组件name获取对象。Full模式下多次调用获取的是同一个对象
        User user1 = applicationContext.getBean("userName1", User.class);

        // 如果IOC容器有两个User类型的对象,则这里获取会报错
        User user2 = applicationContext.getBean(User.class);

        // 通过类class获取多个组件的name
        String[] beanNames = applicationContext.getBeanNamesForType(User.class);
        for(String beanName:beanNames) {
            System.out.println(beanName);		// 返回的结果是:userName1
        }

        // Full模式下通过MyConfig获取的User还是单例
        MyConfig myConfig = applicationContext.getBean(MyConfig.class);
        System.out.println(user2 == myConfig.userName1());      // 返回的结果是: true
    }
}

4. @Import注解

@Import注解说明:

  • 必须配合@Configuration注解使用,否则没有效果
  • 向IOC容器中添加对应类型的组件。默认组件的名称就是全类名
  • 只能添加无参构造器创建的组件

示例程序如下:

package com.hh.springbootTest.myConfig;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import java.util.ArrayList;
import java.util.HashMap;

// 必须配合@Configuration注解使用,否则没有效果
// 向IOC容器中添加对应类型的组件。默认组件的名称就是全类名
@Import({ArrayList.class, HashMap.class})

@Configuration
public class MyConfig {

}

很多功能开关,如@EnableAsync@EnableScheduling,都是通过import来开启功能,添加需要的组件到IOC容器

5. @ImportResource注解

在旧的版本,我们通过编写XML文件,向IOC容器添加bean。为了使用以前编写的XML文件,可以通过@ImportResource注解对resources目录下的XML文件进行引用,就可以将bean添加到IOC容器。注意必须配合@Configuration注解使用,否则没有效果

User类,必须要有无参构造器,如下所示:

package com.hh.springbootTest.myBean;

public class User {

    private String name;

    public User() {

    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "User{" + "name='" + name + "'}";
    }
}

resouces/user.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="userName1" class="com.hh.springbootTest.myBean.User">
        <property name="name" value="user1"></property>
    </bean>

</beans>

对XML文件进行引用,如下所示:

package com.hh.springbootTest.myConfig;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@ImportResource("classpath:user.xml")
@Configuration
public class MyConfig {

}

猜你喜欢

转载自blog.csdn.net/yy8623977/article/details/127636208