前言
Spring是一个非常强大的反转控制(IOC)框架,以帮助分离项目组件之间的依赖关系。因此可以说Spring容器对Bean的注册、管理可以说是它的核心内容,最重要的功能部分。
因此本文主要介绍:向Spring容器注册Bean的多种方式
向Spring IOC容器注册Bean 的7种方式
所有项目建立在SpringBoot2的工程基础上构建(哪怕只用到Spring包,也用此项目构建),pom如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sayabc</groupId> <artifactId>boot2-demo1</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>boot2-demo1</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> <version>1.18.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
1、xml方式(老方式,现在使用得非常的少)
在resource类路径创建一个文件: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="person" class="com.sayabc.boot2demo1.bean.Person"> <property name="name" value="cuzz"></property> <property name="age" value="18"></property> </bean> </beans>
然后main函数采用ClassPathXmlApplicationContext来启动Spring容器容器:
public static void main(String[] args) { ApplicationContext applicationContext = createNewApplicationContext(); Person bean = applicationContext.getBean(Person.class); System.out.println(bean); //Person(name=fsx, age=18) } //创建、启动Spring容器 private static ApplicationContext createNewApplicationContext() { return new ClassPathXmlApplicationContext("classpath:beans.xml"); }
从这便可以看出,这个bean就直接放到Spring容器里面了。
2、@Configuration @Bean配置类的方式
创建一个配置类:
/** * @author fangshixiang * @description * @date 2019-01-30 14:28 */ @Configuration //该注解就相当于一个xml配置文件 public class MainConfig { @Bean(value = "person") public Person person() { return new Person("fsx", 18); } }
这样我们使用AnnotationConfigApplicationContext来启动容器了:
//创建、启动Spring容器 private static ApplicationContext createNewApplicationContext() { return new AnnotationConfigApplicationContext(MainConfig.class); }
效果同上,同样能向容器中放置一个Bean。
@Bean若不指定value值,bean的id默认为方法名的名称。可以指定init-method,destroy-method方法。但是需要注意:单实例Bean容器是管理bean的init和destroy方法的,但是多实例bean容器只管帮你创建和init,之后Spring就不管了
@Bean相关注解:@Scope、@Lazy等
如果是单实例Bean,IOC容器启动时就立马创建Bean,以后获取都从容器里拿(当然你也可以加上@Lazy这个注解,让单实例Bean也懒加载)。如果是多实例Bean,Bean只有获取的时候,获取一次就创建一次。
3、使用@ComponentScan扫描注册组件
只要标注了注解就能扫描到如:@Controller @Service @Repository @component
配置类中加上这个注解:
@Configuration //该注解就相当于一个xml配置文件 @ComponentScan("com.fsx") public class MainConfig { }
实体类上加上一个组件组件,让其能扫描到:
@Component public class Person { private String name; private Integer age; }
启动Spring容器输出可以看到:
//创建、启动Spring容器 private static ApplicationContext createNewApplicationContext() { return new AnnotationConfigApplicationContext(MainConfig.class); } 输出为: Person(name=null, age=null)
备注:这种扫描的方式,请保证一定要有空构造函数,否则报错的。。。
@ComponentScan有很多属性,可以实现更加精确的扫描。比如:basePackageClasses、includeFilters、excludeFilters、lazyInit、useDefaultFilters等。需要注意的是,要使includeFilters生效,需要useDefaultFilters=false才行,否则默认还是全扫
FilterType枚举的过滤类型,可以实现注解、正则等的精确匹配。当然也能CUSTOM自己实现接口来过滤,功能不可谓不强大