欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring MVC学习指南:Beans

程序员文章站 2022-06-06 23:15:59
...

前面提到,Bean是可以通过xml(不推荐)、java配置类、注解,三种方式注册到容器中。

 

注意:默认的生命周期是Singleton。其含义是,在应用中,无论何时、何处,获取这个Bean的实例时,都是共享的同一个实例。因此,在使用Singleton的实例时,需要考虑线程安全的问题。因此,一般将无状态的类设计为Singleton类型。

在容器中,Bean都是通过id进行唯一标记的,在任何位置你都是可以通过指定的id或者Bean的名称获取这个Bean的实例的。但是id、名称并不是必须指定的,如果你不指定,Spring会自动为其生成一个名称。但是,一般为了便于对其进行引用,我们都会对其命名。

 

绑定的优先级:

1. 如果id或名称不存在,则优先根据类型进行绑定。

2. 如果你为其指定了@Primary,或者这个Bean是唯一的,则无需再指定名称。

 

Bean的定义

 

一般包含以下属性:

class 全限定类名
id 唯一标记
name 为其指定的名称
parent 父类
scope 声明周期
constructorargs 构造器参数
properties 属性参数
autowire mode 自动绑定
primary 首选实现
depends-on 依赖Bean的初始化
lazy-init 懒加载。用到再初始化
init-method 初始化方法
destory-method 销毁方法
factory-method 工厂方法
factory-bean 与工厂方法配合使用,用于使用指定的工厂类生产Bean

 

基于xml的示例:

<bean id="xmlTaskService" class="com...XmlDefinedTaskService"
init-method="init" destroy-method="cleanup">
   <constructor-arg ref="userService"/>
   <constructor-arg>
      <bean class="com...TaskInMemoryDAO"></bean>
   </constructor-arg>
</bean>

 

基于注解的示例:

@Service
public class AnnotatedTaskService implements TaskService {

...
   @Autowired
   private UserService userService;

   @Autowired
   private TaskDAO taskDAO;

   @PostConstruct
   public void init() {
      logger.debug(this.getClass().getName() + " started!");
   }

   @PreDestroy
   public void cleanup() {
      logger.debug(this.getClass().getName() + " is about to destroy!");
   }

   public Task createTask(String name, int priority, int createdByuserId, int assigneeUserId) {
      Task task = new Task(name, priority, "Open",
         userService.findById(createdByuserId), null,
         userService.findById(assigneeUserId));
      taskDAO.createTask(task);
      logger.info("Task created: " + task);
      return task;
   }
...
}

 

Bean的初始化

 

通过构造器创建Bean的实例:

<bean id="greeter" class="com...GreetingBean"></bean>
@Component("greeter")
public class GreetingService {
...
}

 

通过静态工厂方法实例化:

<bean id="Greeter" class="...GreetingBean" factory-method="newInstance"></bean>
@Configuration
@ComponentScan(basePackages = "com.springessentialsbook")
public class SpringJavaConfigurator {
...
   @Bean
   public BannerService createBanner() {
      return new BannerServiceImpl();
   }
...
}

xml通过factory-method指定,java配置类则直接通过@Bean注解的方法生产实例。

 

通过实例工厂方法实例化:

通过其他Bean的非静态方法生产实例。

<bean id="greeter"  factory-bean="serviceFactory" factory-method="createGreeter"/>
<bean id="serviceFactory"  class="...ServiceFactory">
<!— ... Dependencies ... -->
</bean>

 

Bean的注入

Spring支持构造器注入,set方法注入两种。

 

构造器注入:

我们SimpleTaskService需要用到UserService、TaskDAO的实例。

public class SimpleTaskService implements TaskService {
...
   private UserService userService;
   private TaskDAO taskDAO;

   public SimpleTaskService(UserService userService, TaskDAO taskDAO) {
      this.userService = userService;
      this.taskDAO = taskDAO;
   }
...
}
<bean id="taskService" class="com...SimpleTaskService"">
   <constructor-arg ref="userService" />
   <constructor-arg ref="taskDAO"/>
</bean>

 

对于简单类型的构造器参数,可以直接在xml中进行配置:

<bean id="systemSettings" class="com...SystemSettings">
   <constructor-arg index="0" type="int" value="5"/>
   <constructor-arg index="1" type="java.lang.String" value="dd/mm/yyyy"/>
   <constructor-arg index="2" type="java.lang.String" value="Taskify!"/>
</bean>

起始的序号从0开始。

 

基于Setter方法的注入:

<bean id="systemSettings" class="com...SystemSettings">
   <property name="openUserTasksMaxLimit" value="5"/>
   <property name="systemDateFormat" value="dd/mm/yyyy"/>
   <property name="appDisplayName" value="Taskify!"/>
</bean>

 

注入List

<bean id="systemSettings" class="com...SystemSettings">
. . .
  <constructor-arg>
    <list>
      <value>[email protected]</value>
      <value>[email protected]</value>
      <value>[email protected]</value>
    </list>
  </constructor-arg>
</bean>

注入对象时,可以使用<ref>替换<value>

 

注入Map

<bean id="systemSettings" class="com...SystemSettings">
. . .
  <property name="emails">
    <map>
      <entry key="admin" value="[email protected]"></entry>
      <entry key="it" value="[email protected]"></entry>
      <entry key="devops" value="[email protected]"></entry>
    </map>
  </property>
</bean>

注入对象时,可以使用<ref>或<bean>替换<value>

 

自动绑定注入

 

可以通过注解构造器方法:

@Service
public class AnnotatedTaskService implements TaskService {
...
   @Autowired
   public AnnotatedTaskService(UserService userService, TaskDAO taskDAO) {
      this.userService = userService;
      this.taskDAO = taskDAO;
   }
...
}

 

可以注解成员变量:

@Service
public class AnnotatedTaskService implements TaskService {
...
   @Autowired
   private UserService userService;
   @Autowired
   private TaskDAO taskDAO;
...
}

 

区分不同的实现的注入:

 

对成员变量使用@Qualifier

@Autowired(required = true)
@Qualifier("taskDAO")
private UserService userService;

对构造器方法的参数:

@Autowired
public AnnotatedTaskService(@Qualifier("userService") UserService userService, @Qualifier("taskDAO") TaskDAO taskDAO) {
   this.userService = userService;
   this.taskDAO = taskDAO;
}

 

相关标签: SpringMVC学习指南

上一篇: mongdb

下一篇: PRML:二元变量分布