Spring(3、基于注解装配Bean)

来源:互联网 发布:linux google输入法 编辑:程序博客网 时间:2024/06/05 04:30

基于注解装配Bean

:本文用到的jar请到Spring(1-1、基于xml装配Bean)中查找    

组件扫描(componentscanning):  Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件。

特定组件包括:

  @Component: 基本注解,标识了一个受 Spring管理的组件

 @Respository:标识持久层组件

 @Service:标识服务层(业务层)组件

 @Controller:标识表现层组件

  对于扫描到的组件,Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写.也可以在注解中通过 value 属性值标识组件的名称

   当在组件类上使用了特定的注解之后,还需要在 Spring 的配置文件中声明<context:component-scan>:

   base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类.

当需要扫描多个包时, 可以使用逗号分隔.

<context:component-scan base-package="com.spring.beans.annotation"  /> 

如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类,示例:

<context:include-filter> 子节点表示要包含的目标类

<context:exclude-filter> 子节点表示要排除在外的目标类

<context:component-scan>下可以拥有若干个 <context:include-filter> 和 <context:exclude-filter> 子节点。

<context:include-filter> 和<context:exclude-filter> 子节点支持多种类型的过滤表达式:

<context:component-scan>元素还会自动注册 AutowiredAnnotationBeanPostProcessor实例,该实例可以自动装配具有 @Autowired @Resource@Inject注解的属性。

@Componentpublic class TestObject {}


package com.spring.beans.annotation.service;import org.springframework.stereotype.Service;@Servicepublic class UserService {public void add() {System.out.println("userService add...");}}


package com.spring.beans.annotation.controller;import org.springframework.stereotype.Controller;@Controllerpublic class UserController {public void execure() {System.out.println("UserController execure...");}}


package com.spring.beans.annotation.repository;public interface UserRepository {void save();}


package com.spring.beans.annotation.repository;import org.springframework.stereotype.Repository;@Repository(value = "userRepository")public class UserRespositoryImpl implements UserRepository {public void save() {System.out.println("UserRespository save...");}}
xml配置:

<!-- 指定IOC容器扫描的包 --><!-- 可以通过resource-pattern匹配扫描的资源 --><!—<context:component-scan base-package="com.spring.beans.annotation" resource-pattern="repository/*.class" />    --><!-- context:exclude-filter子节点排除那些指定表达式的组件 --><!—context:include-filter子节点指定包那些表达式的组件,该节点需要use-default-filters配合使用 --><context:component-scan base-package="com.spring.beans.annotation"use-default-filters="false"><!--<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" /> --><context:include-filter type="annotation"expression="org.springframework.stereotype.Repository" /></context:component-scan>
测试类:

public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml");TestObject testObject = (TestObject) ctx.getBean("testObject");System.out.println(testObject);UserController userController = (UserController) ctx.getBean("userController");System.out.println(userController);UserService userService = (UserService) ctx.getBean("userService");System.out.println(userService);UserRepository userRespository = (UserRepository) ctx.getBean("userRepository");System.out.println(userRespository);}

@AutoWired自动装配Bean

@Autowired 注解自动装配具有兼容类型的单个 Bean属性

构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Authwired 注解

默认情况下, 所有使用 @Authwired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常,若某一属性允许不被设置,可以设置 @Authwired注解的 required属性为 false

默认情况下, IOC容器里存在多个类型兼容的 Bean,通过类型的自动装配将无法工作.此时可以在 @Qualifier注解里提供 Bean的名称. Spring允许对方法的入参标注 @Qualifiter已指定注入 Bean 的名称

 @Authwired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配.

@Authwired 注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean.

@Authwired 注解用在 java.util.Map 上时, 若该 Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值

使用@Resource @Inject自动装配 Bean

Spring 还支持 @Resource @Inject注解,这两个注解和 @Autowired注解的功用类似

@Resource 注解要求提供一个 Bean名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为 Bean的名称

@Inject @Autowired注解一样也是按类型匹配注入的Bean但没有 reqired 属性

建议使用@Autowired注解

泛型依赖注入

package com.spring.beans.generic.di;public class BaseRepository<T> {}package com.spring.beans.generic.di;import org.springframework.beans.factory.annotation.Autowired;public class BaseService<T> {@Autowiredprotected BaseRepository<T> repository;public void add() {System.out.println("add...");System.out.println("repository");}}


package com.spring.beans.generic.di;public class User {}


package com.spring.beans.generic.di;import org.springframework.stereotype.Repository;@Repositorypublic class UserRepository extends BaseRepository<User> {}


package com.spring.beans.generic.di;import org.springframework.stereotype.Service;@Servicepublic class UserService extends BaseService<User> {}
xml配置

<context:component-scan base-package="com.spring.beans.generic.di"></context:component-scan>

测试类:

public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-generic-di.xml");UserService userService = (UserService) ctx.getBean("userService");userService.add();}

整合多个配置文件

Spring 允许通过 <import> 将多个配置文件引入到一个文件中,进行配置文件的集成。这样在启动 Spring容器时,仅需要指定这个合并好的配置文件就可以。

import元素的 resource属性支持 Spring的标准的路径资源

Spring对JDBC的支持

简化JDBC模版查询

为了使 JDBC更加易于使用, Spring JDBC API上定义了一个抽象层,以此建立一个 JDBC存取框架.

作为 Spring JDBC框架的核心, JDBC模板的设计目的是为不同类型的JDBC操作提供模板方法.每个模板方法都能控制整个过程,并允许覆盖过程中的特定任务.通过这种方式,可以在尽可能保留灵活性的情况下,将数据库存取的工作量降到最低。

每次使用都创建一个JdbcTemplate的新实例,这种做法效率很低下.

JdbcTemplate类被设计成为线程安全的,所以可以再 IOC容器中声明它的单个实例,并将这个实例注入到所有的 DAO实例中.

JdbcTemplate也利用了 Java 1.5的特定(自动装箱,泛型,可变长度等)来简化开发

Spring JDBC 框架还提供了一个 JdbcDaoSupport类来简化 DAO实现.该类声明了 jdbcTemplate属性, 它可以从 IOC容器中注入,或者自动从数据源中创建

xml配置:

<!-- 导入配置文件 --><context:property-placeholder location="classpath:db.properties" /><!-- 配置数据源 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="${jdbc.user}"></property><property name="password" value="${jdbc.password}"></property><property name="driverClass" value="${jdbc.driverClass}"></property><property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property><property name="initialPoolSize" value="${jdbc.initPoolSize}"></property><property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property></bean><!--配置Spring的JdbcTemplate工具类 --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean><bean id="employeeDao" class="com.spring.beans.jdbc.EmployeeDao"><property name="jdbcTemplate" ref="jdbcTemplate" /></bean>

JDBC 模板中使用具名参数

在经典的 JDBC用法中, SQL参数是用占位符 ?表示,并且受到位置的限制.定位参数的问题在于,一旦参数的顺序发生变化,就必须改变参数绑定.

Spring JDBC框架中,绑定 SQL参数的另一种选择是使用具名参数(named parameter).

具名参数: SQL按名称(以冒号开头)而不是按位置进行指定.具名参数更易于维护,也提升了可读性.具名参数由框架类在运行时用占位符取代

具名参数只在NamedParameterJdbcTemplate中得到支持

SQL语句中使用具名参数时,可以在一个 Map中提供参数值,参数名为键

也可以使用 SqlParameterSource参数

批量更新时可以提供 Map SqlParameterSource的数组

private NamedParameterJdbcTemplate namedParameterJdbcTemplate;{ctx = new ClassPathXmlApplicationContext("applicationContext.xml");namedParameterJdbcTemplate = ctx.getBean(NamedParameterJdbcTemplate.class);}/** * 使用具名参数时, 可以使用 update(String sql, SqlParameterSource paramSource) 方法进行更新操作 * 1. SQL 语句中的参数名和类的属性一致! * 2. 使用 SqlParameterSource 的 BeanPropertySqlParameterSource 实现类作为参数.  */@Testpublic void testNamedParameterJdbcTemplate2(){String sql = "INSERT INTO employees(last_name, email, dept_id) "+ "VALUES(:lastName,:email,:dpetId)";Employee employee = new Employee();employee.setLastName("XYZ");employee.setEmail("xyz@sina.com");employee.setDpetId(3);SqlParameterSource paramSource = new BeanPropertySqlParameterSource(employee);namedParameterJdbcTemplate.update(sql, paramSource);}


原创粉丝点击