Spring定义Bean的方式
- 1.XML文件配置Bean
- 1.1_构造器创建bean
- 1.2_setter方法创建bean
- 1.3 _静态工厂
- 1.4_ 实例工厂
- 1.5_ FactoryBean
- 2通过注解配置Bean
- 2.1_前提:配置扫描路径
- 2.1.1_spring项目:
- 2.1.2_springboot项目:
- 2.2_使用注解
- 3.通过@Configuration注解配置Bean
- 4.通过@Conditional注解来配置Bean
- 代码示例
- spring中使用比较多的Conditional还有:
- 5.通过@Import注解来配置Bean
- 5.1_普通类
- 6.Spring中bean的创建过程
1.XML文件配置Bean
1.1_构造器创建bean
<bean id="UserService" class="com.wzh.service.UserService">
默认使用无参构造器创建bean.
使用有参构造来创建bean.
<bean id="UserService" class="com.wzh.service.UserService">
<constructor-arg index="0" value="chengdu"></constructor-arg>
<constructor-arg index="1" ref="deviceInfo"></constructor-arg>
</bean>
其中:
index表示下标,从0开始。
value表示常量值.
ref表示引用另一个bean.
1.2_setter方法创建bean
这种方式耦合性相对较低,比有参构造器使用更为广泛。
先定义UserInfo实体:
@Data
public class UserInfo{
private String name;
private int age;
}
它里面包含:成员变量name和age,getter/setter方法。
然后在bean.xml文件中配置bean时,加上标签设置bean所需参数。
<bean id="userInfo" class="com.wzh.service.UserInfo">
<property name="name" value="susan"></constructor-arg>
<property name="age" value="18"></constructor-arg>
</bean>
1.3 _静态工厂
方式要点:1.定义一个工厂类;2.定义一个创建bean的静态方法。
例如:
public class UserInfoBeanFactory {
public static UserInfo createUserInfo(String name, int age) {
return new UserInfo(name, age);
}
}
接下来定义Person类如下:
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserInfo {
private String name;
private int age;
}
它里面包含:成员变量name和age,getter/setter方法,无参构造器和全参构造器。
然后在bean.xml文件中配置bean时,通过factory-method参数指定静态工厂方法,同时通过设置相关参数。
<bean class="com.wzh.service.UserInfoBeanFactory " factory-method="createUserInfo">
<constructor-arg index="0" value="wzh"></constructor-arg>
<constructor-arg index="1" value="18"></constructor-arg>
</bean>
1.4_ 实例工厂
方式要点:1.定义一个工厂类;2.定义一个创建bean的非静态方法。
public class UserInfoBeanFactory {
public UserInfo createUserInfo(String name, int age) {
return new UserInfo (name, age);
}
}
UserInfo类定义同上.
bean.xml文件中配置bean:
1.先配置工厂bean。
2.再配置实例bean时,通过factory-bean参数指定该工厂bean的引用。
// 配置工厂Bean
<bean id="UserInfoBeanFactory " class="com.wzh.service.UserInfoBeanFactory ">
</bean>
// 配置实例Bean
<bean factory-bean="UserInfoBeanFactory " factory-method="createUserInfo">
<constructor-arg index="0" value="wzh"></constructor-arg>
<constructor-arg index="1" value="18"></constructor-arg>
</bean>
1.5_ FactoryBean
大家可以看出上面的实例工厂方法每次都需要创建一个工厂类,不方面统一管理。
这时我们可以使用FactoryBean接口。
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一样配置即可。
<bean id="userFactoryBean" class="com.wzh.service.UserFactoryBean">
</bean>
轻松搞定,so easy。
注意:getBean(“userFactoryBean”);获取的是getObject方法中返回的对象。而getBean("&userFactoryBean");获取的才是真正的UserFactoryBean对象。
我们通过上面五种方式,在bean.xml文件中把bean配置好之后,spring就会自动扫描和解析相应的标签,并且帮我们创建和实例化bean,然后放入spring容器中。
虽说基于xml文件的方式配置bean,简单而且非常灵活,比较适合一些小项目。
但如果遇到比较复杂的项目,则需要配置大量的bean,而且bean之间的关系错综复杂,这样久而久之会导致xml文件迅速膨胀,非常不利于bean的管理。
2通过注解配置Bean
2.1_前提:配置扫描路径
2.1.1_spring项目:
在applicationContext.xml文件中使用<context:component-scan>标签。例如:
<context:component-scan base-package="com.wzh.controller" />
2.1.2_springboot项目:
@ComponentScan(basePackages = "com.wzh")
@SpringBootApplication
public class DataAcquisitionApplication {
public static void main(String[] args) {
SpringApplication.run(DataAcquisitionApplication.class, args);
}
}
// 表示com.wzh路径下的所有类都已经配置了扫描路径,通过添加注解来将bean交给spring管理.
// @ComponentScan(basePackages = {“com.wzh”,"com.base"}): 通过逗号来加载多个包路径.
2.2_使用注解
@Controller 一般用在控制层
@Service 一般用在业务层
@Repository 一般用在数据层
@Component 一般用在公共组件上
通过访问源码发现:三个注解都有使用@Component注解
3.通过@Configuration注解配置Bean
1.在一个类上添加@Configuraiton注解表明这是一个配置类.
在一个方法上面添加@Bean注解来将创建的Bean交给spring管理.
通过@Autowired注解将该Bean注入到使用类中.
2
.代码示例
@Configuration
public class MyConfiguration {
@Bean
public UserInfo getUserInfo() {
return new UserInfo ();
}
}
4.通过@Conditional注解来配置Bean
代码示例
@Service
@ConditionalOnMissingBean(name = "userManageService")
public class DeviceManageService {
// 表示当容器中不存在useManageService时,才会创建deviceManageService.
// 该注解相当于一个开关,通过该注解来控制Bean的创建.
}
spring中使用比较多的Conditional还有:
ConditionalOnBean
ConditionalOnProperty
ConditionalOnMissingClass
ConditionalOnMissingBean
ConditionalOnWebApplication
5.通过@Import注解来配置Bean
5.1_普通类
先定义了User类:
@Data
public class User{
private Long id;
private String name;
}
接下来使用@Import注解导入User类:
@Import(User.class)
@Configuration
public class MyConfig {
}
然后在调用的地方通过 @Autowired注解注入所需的bean。
@RequestMapping("/")
@RestController
public class TestController {
@Autowired
private User user;
@GetMapping("/test")
public void test() {
System.out.println(user);
}
}
定义多个Bean同样可以,只需要在@Import注解中加入多个类即可,用逗号隔开!
@Import({Person.class, User.class})
@Configuration
public class MyConfig {
}
// 该注解同样可以使用在springboot启动类上面,省去MyConfig的配置
6.Spring中bean的创建过程