Spring共有三大核心:IOC,DI,AOP。其中IOC就是将Bean初始化加载到容器中,Bean是如何加载到容器的,可以使用Spring注解方式或者Spring XML配置方式,还有注解与xml混合开发方式(推荐)。
Spring注解方式减少了配置文件内容,更加便于管理,并且使用注解可以大大提高了开发效率!
下面按照分类讲解Spring中常用的一些注解。
一: 创建对象的注解
相当于xml配置文件中编写一个<‘bean’>标签实现的功能
1. 思考:Spring怎么知道应该把哪些Java类当成bean注册到容器中呢?
2. 答案:使用配置文件或者注解的方式进行标识需要处理的java类!代码片
- Component
作用:用于当前类对象存入spring容器中
属性:value——指定bean的id,默认当前类首字母小写
- Controller:一般用在表现层
- Service:一般用在业务层
- Repository:一般用在持久层
- 以上三个注解他们的作用与Component一模一样,他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰
- 小结
1、被注解的java类当做Bean实例,Bean实例的名称默认是Bean类的首字母小写,其他部分不变。@Service也可以自定义Bean名称,但是必须是唯一的!
2、尽量使用对应组件注解的类替换@Component注解,在spring未来的版本中,@Controller,@Service,@Repository会携带更多语义。并且便于开发和维护!
二、用于注入数据的
作用和xml文件中bean标签中写一个标签作用一样
- Autowired:
作用:自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
出现位置: 变量或者方法上
- Qualifier:
作用:在按照类中注入的基础之上再按照名称注入,他在给类成员注入时不能单向度使用,但是再给方法参数注入时可以
属性:value 用于指定注入bean的id
- Resource(jdk11以后不自带)
作用:直接按照bean的id注入,它可以独立使用
属性: name:用于指定bean的id
-
以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。 另外,集合类型注入只能通过xml来实现
-
Value
作用:用于注入基本类型和String类型的数据
属性:
value:用于指定数据的值,可以使用spring中SpEL(el表达式)
SpEL表达式写法:${表达式}
三、 用于改变作用范围的
作用和bean标签使用scope属性实现功能一样
- Scope
作用:用于指定bean的作用范围
常用:singleton prototype
四、 和生命周期相关的
作用和bean标签使用init-method和destory-method作用一样
- PreDestroy:指定销毁方法
- PostConstruct:指定初始化方法
五、spring事务
事务的传播机制和隔离机制比较重要!
事务传播行为类型 | 说明 |
---|---|
PROPAGATION_REQUIRED | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY | 使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作 |
readOnly : 事务的读写属性,取true或者false,true为只读、默认为false
rollbackFor : 回滚策略,当遇到指定异常时回滚。譬如上例遇到异常就回滚
timeout (补充的) : 设置超时时间,单位为秒
isolation : 设置事务隔离级别,枚举类型,一共五种
类型 | 说明 |
---|---|
DEFAULT | 采用数据库默认隔离级别 |
READ_UNCOMMITTED | 读未提交的数据(会出现脏读取) |
READ_COMMITTED | 读已提交的数据(会出现幻读,即前后两次读的不一样) |
REPEATABLE_READ | 可重复读,会出现幻读 |
SERIALIZABLE | 串行化 (对资源消耗较大,一般不使用) |
- 举例
/**
* 账户的业务层实现类
*
* 事务控制应该都是在业务层
*/
@Service("accountService") //业务层注解
@Transactional(propagation= Propagation.SUPPORTS,readOnly=true)//只读型事务的配置
public class AccountServiceImpl implements IAccountService{
@Autowired
private IAccountDao accountDao;
public List<Account> findAllAccount() {
return accountDao.findAllAccount();
}
public Account findAccountById(Integer accountId) { return accountDao.findAccountById(accountId); }
public void saveAccount(Account account) {
accountDao.saveAccount(account);
}
public void updateAccount(Account account) {
accountDao.updateAccount(account);
}
public void deleteAccount(Integer acccountId) {
accountDao.deleteAccount(acccountId);
}
@Transactional(propagation=Propagation.REQUIRED,readOnly=false)//开启读写操作
public void transfer(String sourceName, String targetName, Float money) {
System.out.println("transfer....");
//2.1根据名称查询转出账户
Account source = accountDao.findAccountByName(sourceName);
//2.2根据名称查询转入账户
Account target = accountDao.findAccountByName(targetName);
//2.3转出账户减钱
source.setMoney(source.getMoney()-money);
//2.4转入账户加钱
target.setMoney(target.getMoney()+money);
//2.5更新转出账户
accountDao.updateAccount(source);
//2.6更新转入账户
accountDao.updateAccount(target);
}
}