Spring(3、基于注解装配Bean)
基于注解装配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注解的属性。
@Component
public class TestObject {
}
package com.spring.beans.annotation.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void add() {
System.out.println("userService add...");
}
}
package com.spring.beans.annotation.controller;
import org.springframework.stereotype.Controller;
@Controller
public 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...");
}
}
<!-- 指定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.
使用@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> {
@Autowired
protected 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;
@Repository
public class UserRepository extends BaseRepository<User> {
}
package com.spring.beans.generic.di;
import org.springframework.stereotype.Service;
@Service
public class UserService extends BaseService<User> {
}
<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的特定(自动装箱,泛型,可变长度等)来简化开发
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参数
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
{
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
namedParameterJdbcTemplate = ctx.getBean(NamedParameterJdbcTemplate.class);
}
/**
* 使用具名参数时, 可以使用 update(String sql, SqlParameterSource paramSource) 方法进行更新操作
* 1. SQL 语句中的参数名和类的属性一致!
* 2. 使用 SqlParameterSource 的 BeanPropertySqlParameterSource 实现类作为参数.
*/
@Test
public 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("aaa@qq.com");
employee.setDpetId(3);
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(employee);
namedParameterJdbcTemplate.update(sql, paramSource);
}
上一篇: 你肯定没意识到:概率论在交易中有多重要
下一篇: 概率统计16——均匀分布、先验与后验
推荐阅读
-
Spring(3、基于注解装配Bean)
-
Spring学习记录(四)——Bean的注解装配
-
Spring---使用注解装配Bean(三)
-
Spring定义Bean类(二) Enable*注解装配
-
Spring- 4注解装配bean
-
Spring In Action(二):基于XML配置装配bean
-
第二章 装配Bean(Spring in action,3th)
-
Spring in action 读书笔记(第二章)bean的装配(java类显式配置和spring-test单元测试的使用)
-
SpringBoot根据条件自动装配Bean(基于Condition接口和Conditional注解)
-
spring装配bean的3种方式总结