標註在字段或屬性的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() { }