Spring学习——bean

bean

bean配置

  1. 导入spring的坐标(pom.xml内)spring-context,对应版本5.2.10RELEASE

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    
  2. 配置bean

    <bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl"/>
    
  • id属性标示给bean起名字

  • class属性表示给bean定义类型

  • name属性表示给bean取别名,可以有多个名字,用, ; 或者 空格 分隔

  • scope属性控制bean的作用范围,可选singleton(单例)和prototype(非单例),默认为singleton(单例)

    • BookService bookDao1 = (BookService) ctx.getBean("bookDao");
      BookService bookDao2 = (BookService) ctx.getBean("bookDao");
      
    • 单例时bookDao1和bookDao2是同一个对象
    • 非单例时bookDao1和bookDao2是不同对象
  1. 获取IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  1. 获取bean
BookService bookService = (BookService) ctx.getBean("bookService");
  • 获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常

    NoSuchBeanDefinitionExceptionNoSuchBeanDefinitionException: No bean named 'bookServiceImpl' available
    
  1. 删除业务层中使用new的方式创建的dao对象
//private BookDao bookDao = new BookDaoImpl();
private BookDao bookDao;
  1. 提供对应的set方法
public void setBookDao(BookDao bookDao) {
    this.bookDao = bookDao;
  1. 配置service与dao的属性
<bean id="bookService" class="com.jihua.service.impl.BookServiceImpl">
    <property name="bookDao" ref="bookDao"/>
</bean>
  • property标签表示配置当前bean的属性
  • ref属性表示参照哪一个bean
  • name属性表示配置哪一个具体的属性,其实就是set方法调用set×××()函数时的×××

适合交给容器进行管理的bean

  • 表现层对象
  • 业务层对象
  • 数据层对象
  • 工具对象

不适合交给容器进行管理的bean

  • 封装实体的域对象

实例化bean的三种方式

1. 构造方法实例化bean

  • 调用无参构造方法,无论是public还是private都可以访问到

  • 配置

    • <bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl"/>
      
  • 无参构造方法如果不存在,将抛出异常BeanCreationException

2. 静态工厂实例化bean

  • public class OrderDaoFactory {
    	public static OrderDao get0rderDao(){
    		return new OrderDaoImpl();
    	}
    }
    
  • 需要在配置中指明工厂创建方法factory-method

  • <bean id="orderDao" factory-method="getOrderDao" class="com.jihua.factory.0rderDaoFactory"/>
    

3. 实例工厂实例化bean

  • public class UserDaoFactory {
    	public UserDao getUserDao(){
    		return new UserDaoImpl();
    	}
    }
    
  • 需要在配置中指明工厂创建方法factory-methodfactory-bean

  • <bean id="userDaoFactory" class="com.jihua.factory.UserDaoFactory" />
    <bean id="userDao" factory-method="getUserDao" factory-bean="userDaoFactory"/>
    

4. 使用Factory实例化bean

  • 实例工厂需要实现FactoryBean<?>,泛型为要生成的对象类型
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
	//代替原始实例工厂中创建对象的方法
	public UserDao getobject() throws Exception {
		return new UserDaoImpl();
}
	public class<?> getobjectType() {
		return UserDao.class;
	}
    //控制创建的对象是否为单例(true为单例,false为非单例),一般不写,不写该方法则默认为(true单例)
    public boolean issingleton() {
		return true;
	}
}
  • 配置文件只需要实现该工厂bean即可

  • <bean id="userDao" class="com.jihua.factory.UserDaoFactoryBean"/>
    
  • 多数框架使用的方法

bean的生命周期

生命周期

初始化容器
  1. 创建对象(内存分配)
  2. 执行构造方法
  3. 执行属性注入(set操作)
  4. 执行bean初始化方法
使用bean
  1. 执行业务操作
关闭/销毁容器
  1. 执行bean销毁方法

生命周期控制

1. 配置文件方法
  • 提供生命周期控制方法

    public class BookDaoImpl implements BookDao {
    	public void save( ) {
    		System.out.println( "book dao save ...");
    	}
        //初始化
    	public void init(){
    		System.out.println( "book init ...");
    	}
        //销毁
    	public void destory(){
    		System.out.println( "book destory ...");
    	}
    }
    
  • 配置生命周期控制方法

    <bean id="bookDao” class="com.jihua.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory" />
    
2. 接口控制方式
  • 实现InitializingBean,DisposableBean接口

    public class BookServiceImpl implements BookService, InitializingBean, DisposableBean{
    	public void save() {
    		System.out.println( "book service save ...");
    	}
        //销毁
    	public void afterPropertiesSet( ) throws Exception {
    		System.out.print1n( "afterPropertiesset" );
    	}
        //初始化
    	public void destroy() throws Exception {
    		System.out.println( "destroy" );
    	}
    }
    
3.销毁
  • 销毁一般由tomcat服务器调用

  • 不使用tomcat的时候使用

      1. 手工关闭容器
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    ctx.close();
    
      1. 注册关闭钩子
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    ctx.
    

依赖注入

  • 依赖注入方式
    • setter注入
      • 简单类型
      • 引用类型
    • 构造器注入
      • 简单类型
      • 引用类型

setter注入

  • 引用类型

    • 在bean中定义引用类型属性并提供可访问的set方法

      public class BookServiceImpl implements BookService{
      	private BookDao bookDao;
      	public void setBookDao(BookDao bookDao) {
      		this.bookDao = bookDao;
      	}
      }
      
    • 配置中使用property标签ref属性注入引用类型对象

      <bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl" />
      <bean id="bookService" class="com.jihua.service.impl.BookServiceImpl">
      	<property name="bookDao" ref="bookDao" />
      </bean>
      
  • 简单类型

    • 在bean中定义引用类型属性并提供可访问的set方法

      private int connectionNum;
      private String connectionName;
      
      public void setConnectionNum(int connectionNum) {
          this.connectionNum = connectionNum;
      }
      
      public void setConnectionName(String connectionName) {
          this.connectionName = connectionName;
      }
      
    • 配置中使用property标签value属性注入简单类型数据

      <bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl">
      	<property name="connectionNum" value="10" />
          <property name="connectionName" value="10" />
      </bean>
      
      • Spring内部自动处理数据类型

构造器注入

传统写法
  • 提供有参构造方法

    private BookDao bookDao;
    
    private int connectionNum;
    private String connectionName;
    
    
    public BookServiceImpl(BookDao bookDao, int connectionNum, String connectionName) {
        this.bookDao = bookDao;
        this.connectionNum = connectionNum;
        this.connectionName = connectionName;
    }
    
  • 使用constructor-arg标签value,ref属性注入数据

    <bean id="bookService" class="com.jihua.service.impl.BookServiceImpl">
        <constructor-arg name="bookDao" ref="bookDao" />
        <constructor-arg name="connectionName" value="mysql" />
        <constructor-arg name="connectionNum" value="10" />
    </bean>
    
解耦合写法——参数适配
  • 在constructor-arg标签中使用type属性按照数据类型注入

    <bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl">
    	<constructor-arg type="int" value="10" />
    	<constructor-arg type="java.lang.String" value="mysql"/>
    </ bean>
    
  • 在constructor-arg标签中使用index属性按照参数顺序注入

    <bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl">
    	<constructor-arg index="1" value="10" />
    	<constructor-arg index="0" value="mysql"/>
    </ bean>
    

依赖注入方式选择

  1. 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
  2. 可选依赖使用setter注入进行,灵活性强
  3. Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
  4. 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
  5. 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
  6. 自己开发的模块推荐使用setter注入

依赖自动装配

  • IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配

  • 自动装配方式

    • 按类型(常用)
    • 按名称
    • 按构造方法
    • 不启用自动装配
  • 配置中使用bean标签autowire属性设置自动装配的类型

    <bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl" />
    <bean id="bookService" class="com.jihua.service.impl.BookServiceImpl" autowire="byType"/>
    

自动装配特征:

  • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  • 使用按类型装配时( byType )必须保障容器中相同类型的bean唯一,推荐使用
  • 使用按名称装配时( byName )必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
  • 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

集合注入

  • 注入数组对象

    <property name="array">
    	<array>
    		<value>100</value>
            <value>200</value>
            <value>300</value>
        </array>
    </property>
    
  • 注入List对象(重点)

    <property name="list">
    	<list>
    		<value>itcast</value>
            <value>jihua</value>
            <value>boxuegu</value>
        </list>
    </property>
    
  • 注入Set对象

    <property name="set">
    	<set>
    		<value>itcast</value>
            <value>jihua</value>
            <value>boxuegu</value>
        </set>
    </property>
    
  • 注入Map对象(重点)

    <property name="map">
        <map>
            <entry key= "country" value="china" />
            <entry key="province" value="henan" />
            <entry key="city" value="kaifeng" />
        </map>
    </property>
    
  • 注入Properties对象

    <property name="properties">
    	<props>
    		<prop key="country">china</prop>
            <prop key="province">henan</prop>
            <prop key="city">kaifeng</prop>
        </props>
    </property>
    

加载properties文件

  1. 加载文件

    • 开启命名空间

      在applicationContext.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
             http://www.springframework.org/schema/context/spring-context.xsd
      ">
      
    • 使用context空间加载properties文件

      在applicationContext.xml文件中:

      <context:property-placeholder location="jdbc.properties"/>
      
  2. 使用属性

    • 使用${}读取加载的属性值

      <property name="username" value="${jdbc.username}"/>
      
  • 注意事项

    • 不加载系统属性

      <context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
      
    • 加载多个properties文件

      <context:property-placeholder location="jdbc.properties,msg.properties"/>
      
    • 加载所有properties文件

      <context:property-placeholder location="*.properties" />
      
    • 加载properties文件标准格式

      <context:property-placeholder location="classpath:*.properties"/>
      
    • 从类路径或jar包中搜索并加载properties文件

      <context:property-placeholder location="classpath*:*.properties" >
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值