标注在字段或属性的setter方法上使用。html
@Autowired java
默认是按照byType进行注入的。缓存
@Autowired private PersonDao personDao;
当byType方式找到了多个符合的bean,能够制定byName注解。app
@Autowired @Qualifier("personDaoBean") private PersonDao personDao;
@Resource (这个注解属于J2EE的)的标签ide
默认是按照byName方式注入的。spa
@Resource(name=“personDaoBean”) private PersonDao personDao;//用于字段上
当注解标注在字段上,即默认取字段的名称做为bean名称寻找依赖对象,.net
当注解标注在属性的setter 方法上,即默认取属性名做为bean名称寻找依赖对象。
code
注意:若是没有制定name属性。而且按照默认的名称仍然找不到依赖对象。htm
@Resource注解会byType装配。但一旦指定了name属性,就只能byName装配了对象
注解控制器类
@Controller public class ProductOptionFieldController { }
注解变量,指定按名称
@Autowired @Qualifier("productOptionFieldService") Private transient ProductOptionFieldServiceImpl productOptionFieldService; @Autowired @Qualifier("baseCodeDAO") private transient BaseCodeDAOImpl baseCodeDAO;
注解变量,按类型
@Autowired Private transient ProductOptionFieldServiceImpl productOptionFieldService;
注解Service的实现类
@Service("baseCodeService") public class BaseCodeServiceImpl extends BaseWithoutAuditLogService implements BaseCodeService { }
注视Service实现类中每个重写的方法
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, readOnly = true, timeout = 3) public List<BaseCode> queryBaseCode(BaseCode baseCode) { return baseCodeDAO.queryAll(baseCode); }
Spring事务的传播行为
在service类前加上@Transactional,service全部方法须要事务管理。每个业务方法开始时都会打开一个事务。
Spring默认状况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked
若是遇到checked意外就不回滚。
如何改变默认规则:
1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)
2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
3 不须要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)
在整个方法运行前就不会开启事务 还能够加上: @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true),这样就作成一个只读事务,能够提升效率。
各类属性的意义:
REQUIRED:业务方法须要在一个容器里运行。若是方法运行时,已经处在一个事务中,那么加入到这个事务,不然本身新建一个新的事务。
NOT_SUPPORTED:声明方法不须要事务。若是方法没有关联到一个事务,容器不会为他开启事务,若是方法在一个事务中被调用,该事务会被挂起,调用结束后,原先的事务会恢复执行。
REQUIRESNEW:无论是否存在事务,该方法总汇为本身发起一个新的事务。若是方法已经运行在一个事务中,则原有事务挂起,新的事务被建立。
MANDATORY:该方法只能在一个已经存在的事务中执行,业务方法不能发起本身的事务。若是在没有事务的环境下被调用,容器抛出例外。
SUPPORTS:该方法在某个事务范围内被调用,则方法成为该事务的一部分。若是方法在该事务范围外被调用,该方法就在没有事务的环境下执行。
NEVER:该方法绝对不能在事务范围内执行。若是在就抛例外。只有该方法没有关联到任何事务,才正常执行。
NESTED:若是一个活动的事务存在,则运行在一个嵌套的事务中。若是没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务 拥有多个能够回滚的保存点。内部事务的回滚不会对外部事务形成影响。它只对DataSourceTransactionManager事务管理器起效。
@Transactional注解的属性说明
属性 |
类型 |
描述 |
|
枚举型: |
可选的传播性设置 |
|
枚举型: |
可选的隔离性级别(默认值:ISOLATION_DEFAULT) |
|
布尔型 |
读写型事务 vs. 只读型事务 |
|
int型(以秒为单位) |
事务超时 |
|
一组 |
一组异常类,遇到时 必须 进行回滚。默认状况下checked exceptions不进行回滚,仅unchecked exceptions(即RuntimeException的子类)才进行事务回滚。 |
|
一组 |
一组异常类名,遇到时 必须 进行回滚 |
|
一组 |
一组异常类,遇到时 必须不 回滚。 |
|
一组 |
一组异常类,遇到时 必须不 回滚 |
注解缓存,该方法返回值放入到缓存当中
@Cacheable public List<BaseCode> queryByCodeType(int codeType) { List<BaseCode> list =baseCodeDAO.selectByCodeType(codeType); return list; }
@Cacheable注解能够用在方法或者类级别。当他应用于方法级别的时候,就是如上所说的缓存返回值了。
当应用在类级别的时候,这个类的全部方法的返回值都将被缓存。
@Cacheable(value = "employee")public class EmployeeDAO { public Person findEmployee(String firstName, String surname, int age) { return new Person(firstName, surname, age); } public Person findAnotherEmployee(String firstName, String surname, int age) { return new Person(firstName, surname, age); }}
@Cacheable注解有三个参数,value是必须的,还有key和condition。第一个参数,也就是value指明了缓存将被存到什么地方。
@Cacheable(value = "employee") public Person findEmployee(String firstName, String surname, int age) { return new Person(firstName, surname, age); }
上面的代码保证findEmployee的返回值Person对象将被存储在"employee"中。
任何存储在缓存中的数据为了高速访问都须要一个key。Spring默认使用被@Cacheable注解的方法的签名来做为key,固然你能够重写key,自定义key可使用SpEL表达式。
@Cacheable(value = "employee", key = "#surname") public Person findEmployeeBySurname(String firstName, String surname, int age) { return new Person(firstName, surname, age); }
在findEmployeeBySurname()的注解中"#surname"是一个SpEL表达式,他将使用findEmployeeBySurname()方法中的surname参数做为key。
@Cacheable的最后一个参数是condition(可选),一样的,也是引用一个SpEL表达式。可是这个参数将指明方法的返回结果是否被缓存。
@Cacheable(value = "employee", condition = "#age < 25") public Person findEmployeeByAge(String firstName, String surname, int age) { return new Person(firstName, surname, age); }
上面的例子中,只有年龄小于25的时候才被缓存。
在快速看完了如何使用缓存后,咱们接下来看看缓存带来的效果。
<A href="http://my.oschina.net/test45" target=_blank rel=nofollow>@Test</A> public void testCache() { Person employee1 = instance.findEmployee("John", "Smith", 33); Person employee2 = instance.findEmployee("John", "Smith", 33); assertEquals(employee1, employee2); }
上面的例子很简单,第一次调用findEmployee,findEmployee方法将被执行,Spring将他的返回值一个person对象存 入缓存。第二次调用findEmployee的时候findEmployee将不被执行,Spring直接将缓存中的数据做为返回值返回。因此 employee1 和employee2引用了一样的对象。
最后总结一下流程,当执行到一个被@Cacheable注解的方法 时,Spring首先检查condition条件是否知足,若是不知足,执行方法,返回;若是知足,在value所命名的缓存空间中查找使用key存储的 对象,若是找到,将找到的结果返回,若是没有找到执行方法,将方法的返回值以key-对象的方式存入value缓存中,而后方法返回。
@Cacheable:声明一个方法的返回值应该被缓存。
@CacheFlush:声明一个方法是清空缓存的触发器。
@CacheFlush(key="com.isoftstone.ebiz.insurance.app.common.service.impl.BaseCodeServiceImpl.queryByCodeType", isPrefix = true) public void cacheFlushBaseCode() { }