注解配置
Spring
容器中的Bean
对象是由Spring
创建的则可使用注解
启用注解
在
Spring
的配置文件中加入<context:annotation-config/>
标签即可启用注解配置
启用
注解配置
时,依赖Spring-aop.jar
使用注解配置
可以减少xml
的配置
- 使用
<context:annotation-config/>
标签启用注解配置
示例如下:
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 启用注解方式配置 -->
<context:annotation-config></context:annotation-config>
Bean
对象由Spring
的IOC
容器创建和管理时,可使用以下注解:@Autowired
: 自动装配。用于Bean
对象的成员变量和set
方法上- 根据成员变量或者
set
方法形参类型自动注入 - 如果
Spring
的IOC
容器中有多个可选相同类型的Bean
对象,可配合使用@Qualifier("bean_id")
根据Bean
对象的id
属性进行自动装配 - 使用注解的
@Autowired
进行自动配置后,可不再提供用于xml
配置属性注入的set
方法 @Resource
是与@Autowired
、@Qualifier("bean_id")
组合等效的注解@Resource
是java
自带(javax.annotation.Resource
)的注解(根据javaEE
规范),@Autowired
、@Qualifier("bean_id")
是Spring
框架提供的注解@Resource
是根据Bean
对象的变量名字进行自动注入,可用在变量和set
方法上- 可以在
@Resource
注解中使用name
属性指定需要注入的变量的名字
例如:
@Resource(name = "productMapper") private ProductMapper productMapper;
- 根据成员变量或者
@Autowired @Qualifier("productMapper") private ProductMapper productMapper;
@PostConstruct
: 指定被注解的方法为初始化方法(对象在创建完成以后执行,即构造方法之后执行)- 初始化方法实现还可以通过实现
InitializingBean
接口以及在Spring
的xml
配置文件中使用<bean>
元素的init-method
属性指定 - 执行初始化方法时,
Bean
对象的属性已经注入依赖
- 初始化方法实现还可以通过实现
PreDestroy
: 指定被注解的方法为销毁方法(对象在销毁之前执行,即关闭Spring
的IOC
容器时,即关闭Tomcat
时)- 销毁方法实现还可以通过实现
DisposableBean
接口以及在Spring
的xml
配置文件中使用<bean>
元素的destroy-method
属性指定
- 销毁方法实现还可以通过实现
初始化和销毁方法的实现方法都有3种,分别为
实现接口
、xml属性
、注解
。其同时使用时的优先顺序如下:注解
->实现接口
->xml属性
如果
Bean
对象的scope
属性值为prototype
(原型),则Spring
仅执行Bean
对象的初始化,并不负责执行Bean
对象的销毁,Bean
对象的销毁交由JVM
执行@Value
: 用于根据.properties
属性配置文件的键值对进行注入属性值- 需要在
Spring
的配置文件中加入属性占位符的配置
示例如下:
<!-- 属性占位符 --> <context:property-placeholder location="classpath:db.properties" ignore-unresolvable="true"></context:property-placeholder>
- 在
@Value
注解中使用EL
表达式指明注解注入的属性值对应键值对的键- 使用
@Autowired
、@Resource
注入的是一个对象,使用@Value
注入的是值
例如:
- 使用
@Value("${db.url}") private String url;
- 或者直接进行以下配置在使用
@Value
注解:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <array><value>classpath:value.properties</value></array> </property> </bean>
- 需要在
组件扫描
- 在
Spring
的xml
中使用<context:component-scan base-backage=""/>
标签启用组件扫描
- 启用
组件扫描
后,组件内部的注解会被自动识别生效,故可不用再进行注解配置 base-package
属性指定需要扫描的包,在该包及其子包中带有如下注解的Bean
对象会被自动注册到Spring
的IOC
容器中注解 说明 @Component
通用组件 @Controller
控制器 @Service
服务类 @Repository
数据访问 - 可以使用注解的
value
属性指定被扫描到Spring
的IOC
容器的Bean
对象的名字- 如未使用
value
属性,则其Bean
对象在Spring
容器中的名字默认为其简单名(即首字母小写)
- 如未使用
- 可以使用注解的
- 若需要扫描的包有多个,则可在
base-package
属性中使用,
或;
分隔
例如:
<!-- 启用注解方式配置 --> <!-- <context:annotation-config></context:annotation-config> --> <!-- 组件扫描自动启用注解配置 --> <context:component-scan base-package="com.Spring.web.service,com.Spring.web.dao.test"/>
- 可以使用
<context:component-scan>
的子元素<context:exclude-filter>
排除某些带有指定注解的类不被扫描到Spring
容器中expression
属性指定排除的注解类型
例如:
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
- 启用
组件扫描
到Spring
的IOC
容器中的Bean
对象默认是单例的- 可使用
@Scope("singleton")
进行Bean
对象作用域的配置
- 可使用
启用注解方式的事务控制
- 使用注解驱动可使用注解方式进行事务控制
- 使用
<tx:annotation-driven>
配置注解驱动 - 使用
transaction-manager
属性设置事务管理器 - 根据代码中的注解进行事务控制,不再需要在
Spring
的xml
配置文件中进行事务配置
示例如下:
- 使用
<!-- 事务 注解 驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- <tx:advice id="transactionAdvice" transaction-manager="transactionManager">-->
<!-- <tx:attributes>-->
<!-- <tx:method name="find*" read-only="true"/>-->
<!-- <tx:method name="setProductDao" propagation="NEVER"></tx:method>-->
<!--<!– <tx:method name="find*" read-only="true" rollback-for="java.lang.Exception"/>–>-->
<!-- </tx:attributes>-->
<!-- </tx:advice>-->
<!-- <aop:config>-->
<!-- <aop:pointcut id="pc1" expression="execution(public * com.Spring.web.service..*.*(..))"/>-->
<!-- <aop:advisor advice-ref="transactionAdvice" pointcut-ref="pc1"></aop:advisor>-->
<!-- </aop:config>-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
- 使用
@Transactional
注解的方法带有事务控制- 使用
@Transactional(readOnly = true)
指明当前事务是只读事务 propagation
属性指明事务的传播属性isolation
属性指明事务的隔离级别timeout
属性指明事务的超时时间rollbackForClassName
属性指明事务的异常回滚类noRollbackForClassName
属性指明事务的异常不回滚类- 不设置则默认是运行时异常回滚
- 使用
- 将
@Transactional
注解使用在类上,则类中的所有方法在执行时都有事务控制- 如果将
@Transactional
注解加在类上,则该类中的所有方法被调用时都被织入事务advice
- 如果将注解加在方法上,则该方法被调用时将被织入事务
advice
,没有标注@Transactional
的方法不会有事务
示例如下:
- 如果将
package com.Spring.web.service;
import com.Spring.web.bean.ProductInfo;
import com.Spring.web.dao.ProductDao;
import com.Spring.web.mapper.ProductMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.SQLException;
import java.util.List;
@Service("productService")
@Scope("singleton")
public class ProductServiceImpl implements ProductService {
private ProductDao productDao;
@Autowired
@Qualifier("productMapper")
private ProductMapper productMapper;
public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}
@Override
@Transactional(readOnly = true)
public List<ProductInfo> findAllProducts() {
List<ProductInfo> list = null;
try {
list = this.productMapper.findAllProducts();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return list;
}
@Override
@Transactional
public int saveInfo(ProductInfo info) {
return this.productMapper.saveInfo(info);
}
@Override
@Transactional
public int delete(Integer[] proId) {
return this.productMapper.delete(proId);
}
}