【一步一步学习spring】spring bean管理(下)

3. 依赖注入

3.1 spring的属性注入(xml方式)

  • 构造方法注入
  • 属性setter方法注入

3.1.1 构造方法注入

  • 通过构造方法注入bean的属性值或依赖的对象,它保证了bean实例在实例化就可以使用
  • 构造器注入在<constructor-arg>元素中声明属性
<bean id = "user" class="com.ioc.demo4.User">
    <constructor-arg name="name" value="xxx"></constructor-arg>
    <constructor-arg name="age" value="29"></constructor-arg>
</bean>

3.1.2 set方法注入

  • 同过<property>设置注入的属性
<bean id="cat" class="com.ioc.demo4.Cat">
    <property name="name" value="ccc"></property>
</bean>
<bean id="person" class="com.ioc.demo4.Person">
    <property name="name" value="aaa"></property>
    <property name="age" value="88"></property>
    <property name="cat" ref="cat"></property>
</bean>

3.1.3 c名称空间

  • 为了简化XML文件配置
  • c:<属性名>="xxx"引入常量值
  • c<属性名>-ref="xxx" 引入其他bean对象

引入c包

xmlns:p="http://www.springframework.org/schema/c"
<bean id="user" class="com.ioc.demo4.User" c:name="ooo" c:age="88"></bean>

3.1.4 p名称空间

  • 为了简化XML文件配置,spring从2.5开始引入一个新的p名称空间
  • p:<属性名>="xxx"引入常量值
  • p:<属性名>-ref="xxx" 引入其他bean对象

引入p包

xmlns:p="http://www.springframework.org/schema/p"
<bean id="cat" class="com.ioc.demo4.Cat" p:name="xiaohuang"></bean>
<bean id="person" class="com.ioc.demo4.Person" p:name="aaa" p:age="99" p:cat-ref="cat"></bean>

3.1.5 SpEL注入

  • SpEL:spring expression language, spring表达式语言,对依赖注入进行简化
  • 语法:#
  • <bean id="" value="#{表达式}">
<bean id="cat" class="com.ioc.demo4.Cat" p:name="#{'xiaohuang'}"></bean>
<bean id="person" class="com.ioc.demo4.Person" p:name="#{'aaa'}" p:age="#{99}" p:cat="#{cat}"></bean>

当然表达式可以是java语句,可以用其他bean的方法来给目标bean赋值。

比如age是Manger类中管理的。

<bean id="manage" class="com.ioc.demo4.Manager"></bean>

<bean id="cat" class="com.ioc.demo4.Cat" p:name="#{'xiaohuang'}"></bean>
<bean id="person" class="com.ioc.demo4.Person" p:name="#{'aaa'}" p:age="#{manage.getAge('aaa')}" p:cat="#{cat}"></bean>

3.1.6 复杂类型的属性注入

<!-- 复杂类型的bean属性注入 -->
<bean id="collection" class="com.ioc.demo4.CollectionBean">
    <!-- 数组 -->
    <property name="array">
        <array>
            <value>xxx</value>
            <value>qqq</value>
            <value>www</value>
        </array>
    </property>

    <!-- 列表 -->
    <property name="list">
        <list>
            <value>111</value>
            <value>222</value>
            <value>333</value>
            <value>444</value>
        </list>
    </property>

    <!-- 集合 -->
    <property name="set">
        <set>
            <value>xiaohuang</value>
            <value>xiaohuang</value>
            <value>xiaohong</value>
        </set>
    </property>

    <!-- 字典 -->
    <property name="map">
        <map>
            <entry key="x" value="xxx"></entry>
            <entry key="y" value="yyy"></entry>
            <entry key="z" value="zzz"></entry>
        </map>
    </property>
</bean>

3.2 spring的属性注入(注解方式)

3.2.1 使用注解定义Bean

  • @Component 描述Spring框架中的Bean
  • 除了@Component外,spring提供了3个功能基本和@Component等效的注解,为了区分类功能
    • @Repository 用于对Dao实现类进行标注
    • @Service 用于对Service实现类进行标注
    • @Controller 用于对Controller实现类进行标注
  • xml 头修改为:
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:c="http://www.springframework.org/schema/c"
    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">
  • xml开启注解扫描,配置包扫描路径
<context:component-scan base-package="com.ioc"></context:component-scan>
  • bean
@Component("abean1")
public class Bean1 {
	public void sayHello() {
		System.out.println("hello");
	}
}
  • 调用
public void demo1() {
    ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
    Bean1 bean = (Bean1)context.getBean("abean1");
    bean.sayHello();
}

3.2.2 使用注解注入属性

  • 普通类型属性
    • 使用@Value进行自动注入
@Value("aaa")
private String name;
  • 对象类型属性

    • 使用@Autowired进行自动注入

    • @Autowired默认按照类型进行注入

    • @Autowired注入时可以针对成员变量或者set方法

      • 依赖类Bean1Dao
      @Repository("bean1dao")
      public class Bean1Dao {
      	@Value("dao")
      	private String name;
      	@Override
      	public String toString() {
      		return "Bean1Dao [name=" + name + "]";
      	}
      }
      
      • 引用类Bean1
      @Autowired
      private Bean1Dao dao;
      
    • 在@Autowired下边添加@Qualifier也可以指定名称。

      • 引用类Bean1
      @Autowired
      @Qualifier("bean1dao")
      private Bean1Dao dao;
      
    • 当然,使用@Resource可以代替上边的这两个注解

      • 引用类Bean1
      @Resource(name="bean1dao")
      private Bean1Dao dao;
      

      如果出现没有@Resource注解的情况,需要引入下边的依赖包

      <dependency>
          <groupId>javax.annotation</groupId>
          <artifactId>jsr250-api</artifactId>
          <version>1.0</version>
      </dependency>
      

3.3 spring的其他注解

3.3.1 初始化和销毁方法

Spring初始化bean或销毁bean时,有时需要做一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。

xml配置的方法时:

<bean id="xxx" class="...Yoo" init-method="init" destory-method="destory" />

注解的方式:

@PostConstruct 初始化

@PreDestroy 销毁(只有单例下有效)

bean中可以添加

@PostConstruct
private void init() {
    System.out.println("init......");
}
@PreDestroy
private void destroy() {
    System.out.println("destory.......");
}

3.3.2 bean的scope

  • 使用注解配置的bean和<bean>配置是一样的,默认是singleton
  • @Scope注解用于指定Bean的作用范围

4. 传统xml配置和注解配置混合使用

  • xml方式的优势
    • 结构清晰,易于阅读
  • 注解方式的优势
    • 开发便捷,属性注入方便

故我们应该取其优势使用,使用xml方式来管理bean,使用注解方式做属性注入。

  • xml管理bean
<context:annotation-config/>
<bean id="categorydao" class="com.ioc.mix.demo.CategoryDao"/>
<bean id="productdao" class="com.ioc.mix.demo.ProductDao"/>
<bean id="productservice" class="com.ioc.mix.demo.ProductService"/>

可以看到上面的xml中多了一个<context:annotation-config/>,这个是把属性注入的注解开启。而我们前面用到的<context:component-scan base-package="com.xxx">是把所有的注解都打开。

  • annotation来做属性注入
package com.ioc.mix.demo;

import org.springframework.beans.factory.annotation.Autowired;

public class ProductService {
	
	@Autowired
	private CategoryDao categorydao;
	
	@Autowired
	private ProductDao productdao;
	
	public void save() {
		System.out.println("product service save");
		categorydao.save();
		productdao.save();
	}
}

posted @ 2018-09-05 11:15  麦兜爱学习  阅读(593)  评论(0编辑  收藏  举报