Spring中Bean的配置

来源:互联网 发布:淘宝宝宝棉绸布料 编辑:程序博客网 时间:2024/05/28 09:31

Bean的配置

可以把Spring看做一个大型的工厂,而Spring容器中的Bean就是该工厂的产品。要想使用这个工厂生产和管理Bean,就需要在配置文件中告诉它需要哪些Bean,以及需要使用何种方式将这些Bean装配到一起。

XML配置文件的根元素是beans,beans中包含了多个bean子元素,每一个bean子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中。

bean元素中的属性:

  • id:是一个Bean的唯一标识,Spring容器对Bean的配置、管理都通过该属性来完成。
  • class:该属性指定了Bean的具体实现类,它必须是一个完整的类名,使用类的全限定名。
  • scope:用来设定Bean实例的作用域,其属性值有singleton(单例)、propotype(原型)、request、session和global Session。其默认值是singleton。
  • property:bean元素的子元素,用于调用Bean实例中的Setter方法完成属性赋值,从而完成依赖注入。该元素的name属性指定Bean实例中的响应属性名,属性值可通过ref或value属性直接指定(值类型用value,引用类型用ref)。

在配置文件中,通常一个普通的Bean只需要定义id和class两个属性即可。

Bean的实例化

在面向对象的程序中,要想使用某个对象,就需要先实例化这个对象。在Spring中,实例化Bean有三种方式,分别为构造器实例化、静态工厂方式实例化和实例工厂方式实例化。

构造器实例化

构造器实例化是指Spring容器通过Bean对应的类中默认的构造函数来实例化Bean。就是IoC那个例子。

静态工厂方式实例化

实例工厂方式实例化

Bean的作用域

  • singleton:单例模式,使用singleton定义的Bean在Spring容器中将只有一个实例,也就是说,无论有多少个Bean引用它,始终将指向同一个对象。这也是Spring容器默认的作用域。单例模式对于无会话状态的Bean(如Dao组件、Service组件)来说,是最理想的选择。
  • prototype:原型模式,每次通过Spring容器获取的prototype定义的Bean时,容器都将创建一个新的Bean实例。对需要保持会话状态的Bean(如Struts2的Action类)应该使用。
  • request
  • session
  • global Session

Bean的生命周期

Bean的装配方式

Bean的装配方式即Bean的依赖注入的方式。

基于XML的装配

基于Annotation(注解)的装配

  • @Component:可以使用此注解描述Spring中的Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
  • @Constroller:作用在控制层(如Struts2的Action),功能与@Component一样
  • @Service:作用在业务层(Service层)
  • @Repository:作用在数据访问层(DAO层)
  • @Autowired:用于对Bean的属性变量、属性的Set方法及构造函数进行标注,配合对应的注解处理器完成Bean的自动配置工作。默认按照Bean的类型进行装配。
  • @Resource:作用域Autowired一样。其区别在于@Autowired默认按照Bean类型装配,而@Resource默认按照Bean实例名称进行装配。@Resource中有两个重要属性:name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。如果指定name属性,则按实例名称进行装配;如果指定type属性,则按Bean类型进行装配;如果都不指定,则先按Bean实例名称装配,如果不能匹配,再安装Bean类型进行装配;如果都无法匹配,则抛出NoSuchBeanDefinitionException异常。
  • @Qualifier:与@Autowired注解配合使用,会将默认的按Bean类型装配修改为按Bean的实例名称装配,Bean的实例名称由@Qualifier注解的参数指定。
  • @Scope(“prototype”)多例
  • 生命周期 初始化:@PostConstruct 销毁:@PreDestroy

在配置文件中更改

<?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                            http://www.springframework.org/schema/context/spring-context.xsd">    <!-- 组件扫描,扫描含有注解的类 -->    <context:component-scan base-package="com.itcast.annotation"></context:component-scan></beans>

和之前的例子相比schema约束增加了第4行和7,8行。这个约束还是从之前的那个xsd-config.html中找。

然后使用context命名空间的component-scan元素进行注解的扫描,其base-package属性用来通知spring所需要扫描的目录。

定义一个dao层的接口

public interface BookDao {    void addBook();}

定义一个dao层的实现类

@Repository("bookDao")public class BookDaoImpl implements BookDao {    @Override    public void addBook() {        System.out.println("di  add book");    }}

定义一个Service层的接口

public interface BookService {    void addBook();}

定义一个Service层的实现类

@Service("bookService")public class BookServiceImpl implements BookService {    @Resource(name="bookDao")    private BookDao bookDao;    public void setBookDao(BookDao bookDao) {        this.bookDao = bookDao;    }    @Override    public void addBook(){        this.bookDao.addBook();    }}

测试类

public class TestIoC {    @Test    public void demo01(){        //1 获得容器        String xmlPath="/spring/src/applicationContext.xml";        ApplicationContext applicationContext=new ClassPathXmlApplicationContext(xmlPath);        //2.获得对象        UserService userService = (UserService) applicationContext.getBean("bookService");        userService.addUser();    }}

@Repository注解将BookDaoImpl类标识为Spring中的Bean,其写法相当于配置文件中的

<bean id="bookDao" class="cn.itcast.annotation.BookDaoImpl"/>

@Resource注解标注在属性bookDao上(也可标注在bookDao的set方法上),这相当于配置文件中

<property name="bookDao" ref="bookDao"/>