前言

注解配置和 xml 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。关于实际的开发中到底使用xml还是注解,每家公司有着不同的使用习惯。所以这两种配置方式我们都需要掌握。

本文的注解配置,采用 上篇文章 的案例,把 spring 的 xml 配置内容改为使用注解逐步实现。

  1. 使用 @Repository 注解管理持久层(省略持久层接口,所改变的是它的实现类)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Repository
    public class AccountDaoImpl implements IAccountDao {

    /**
    * 使用 @Autowired 注解自动按照类型注入,所以此处无需 setter 方法了
    */
    @Autowired
    private QueryRunner queryRunner;

    // ....

    // ... 此处省略 CRUD 方法,因为和上篇文章是一样的
    }
  2. 使用 @Service 注解管理 业务层(省略业务层接口,所改变的是它的实现类)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Service
    public class AccountServiceImpl implements IAccountService {

    /**
    * 使用 @Autowired 注解自动按照类型注入,所以此处无需 setter 方法了
    */
    @Autowired
    private IAccountDao accountDao;

    // ....

    // ... 此处省略 CRUD 方法,因为和上篇文章是一样的
    }
  3. 修改 XML 配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <?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="cn.imzjw"/>

    <!--配置 queryRunner-->
    <bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
    <!--注入数据源-->
    <constructor-arg name="ds" ref="dataSource"/>
    </bean>

    <!--配置数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <!--连接数据库的必备信息-->
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"/>
    <property name="user" value="garvey"/>
    <property name="password" value="garvey"/>
    </bean>

    </beans>
  4. 测试类不做改变,测试结果一模一样

常用注解

用于创建对象的

相当于XML中的 <bean id="" class="">

作用:把资源交给 spring 来管理。相当于在 xml 中配置一个 bean

属性:value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。

他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。 他们只不过是提供了更加明确的语义化。

  • @Controller:一般用于表现层的注解。
  • @Service:一般用于业务层的注解。
  • @Repository:一般用于持久层的注解。

注:如果注解中有且只有一个属性要赋值时,且名称是 value,value 在赋值是可以不写

用于注入数据的

相当于XML中的 <property name="" ref=""><property name="" value="">

作用:自动按照类型注入。当使用注解注入属性时,set 方法可以省略。它只能注入其他 Bean 类型。当有多个 类型匹配时,使用要注入的对象变量名称作为 Bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。

  • 作用:在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和 @Autowired一起使用;但是给方法参数注入时,可以独立使用。
  • 属性:value:指定 bean 的 id。
  • 作用:直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。
  • 属性:name:指定 bean 的 id。
  • 作用:注入基本数据类型和 String 类型数据
  • 属性:value:用于指定值

用于改变作用范围的

相当于 XML 中的 <bean id="" class="" scope="">

  • 作用:指定 bean 的作用范围。
  • 属性:value:指定范围的值。
    • 取值:singleton、prototype、request、session、globalsession

和生命周期相关的

相当于 XML 中的 <bean id="" class="" init-method="" destroy-method="" />

用于指定初始化方法。

用于指定销毁方法。

思考

写到此处,基于注解的 IOC 配置已经完成,但是大家都发现了一个问题,我们依然离不开 Spring 的 XML 配置文件,那么能不能不写这个 bean.xml,所有配置都用注解来实现呢?

总结

我们选择哪种配置的原则是简化开发和配置方便,而非追求某种技术。