淺談spring 常用注解
我們不妨先將spring常用的注解按照功能進行分類
1 、將普通類加入容器形成Bean的注解
日常開發(fā)中主要使用到的定義Bean的注解包括(XML方式配置bean暫不討論):
@Component、@Repository、@Service、@Controller、@Bean
其中@Component、@Repository、@Service、@Controller實質(zhì)上屬于同一類注解,用法相同,功能相同,區(qū)別在于標(biāo)識組件的類型。當(dāng)一個組件代表數(shù)據(jù)訪問層(Dao)時,你可以給它加上@Repository注解,如下例:
@Repository
public class BiliAPIDaoImpl implements BiliAPIDao {
private final static Logger LOGGER = LoggerFactory.getLogger(BiliAPIDaoImpl.class);
private BiliAPIHttpClient asoAPIHttpClient;
public void execute(){
//some logic business
}
}
當(dāng)組件用于業(yè)務(wù)層時,使用@Service注解,如下例:
@Service(value="SecUserService")
public class SecUsersServiceImpl implements SecUsersService {
@Autowired
private SecUsersDao secUsersDao;
@Autowired
private SecRoleUserService secRoleUserService;
public void doBusiness(){
//do some business
}
}
注意,在此處的@Service注解中額外添加了value=”SecUserService”的屬性,為何對此一舉呢?value屬性可以指定生成后Bean的名稱,這個名稱便成為容器中bean 的唯一標(biāo)識符。同樣的,在@Component、@Repository、@Controller也均可以指定其value值,當(dāng)然,是如有必要時加
當(dāng)組件屬于控制層時,則使用@Controller注解;當(dāng)組件不能進行很好地歸類時,那我們可以使用@Component注解。因使用方式均相同,故此處不再繼續(xù)貼代碼
在這幾個注解中,額外需要留意的是@Bean注解。不妨看代碼:
@Component
public class FactoryMethodComponent {
private static int i;
@Bean @Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
// use of a custom qualifier and autowiring of method parameters
@Bean
protected TestBean protectedInstance(@Qualifier("public") TestBean spouse,
@Value("#{privateInstance.age}") String country) {
TestBean tb = new TestBean("protectedInstance", 1);
tb.setSpouse(tb);
tb.setCountry(country);
return tb;
}
@Bean @Scope(BeanDefinition.SCOPE_SINGLETON)
private TestBean privateInstance() {
return new TestBean("privateInstance", i++);
}
@Bean @Scope(value = WebApplicationContext.SCOPE_SESSION,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public TestBean requestScopedInstance() {
return new TestBean("requestScopedInstance", 3);
}
}
Bean注解主要用于方法上,有點類似于工廠方法,當(dāng)使用了@Bean注解,我們可以連續(xù)使用多種定義bean時用到的注解,譬如用@Qualifier注解定義工廠方法的名稱,用@Scope注解定義該bean的作用域范圍,譬如是singleton還是prototype等。
此處還得另外提一個注解: @Configuration.實際上,上面談到的@Bean注解更多時候是與@Configuration注解在一起使用的。如果將一個類標(biāo)注為@Configuration注解,那么也就意味著這個class將會作為創(chuàng)建各種bean的工廠(類似于一個新的容器)。最簡單的配合使用示例如下:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
以上的代碼實際上等價于Xml中的配置:
<beans> <bean class="com.acme.services.MyServiceImpl" id="myService"> </bean></beans>
我們還需要注意的一點,在Spring的@Component注解中使用@Bean與在Spring中的@Configuration使用是一定的差別的。在使用@Component的類中不會強制使用CGLIB代理攔截方法和屬性。而在@Configuration類中,則會使用CGLIB代理去調(diào)用@Bean標(biāo)注的方法并返回對象的引用。在@Configuration注解中使用@Bean也可以防止同一個@Bean方法被意外調(diào)用多次時而產(chǎn)生細微的難以排查的錯誤
2、從容器中取Bean(裝配bean)時常用的注解
開發(fā)中最常用到的用于裝配的注解是:@Autowired和@Resource
@Autowired注解:
public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
@Autowired注解可用于為類的屬性、構(gòu)造器、方法進行注值。默認情況下,其依賴的對象必須存在(bean可用),如果需要改變這種默認方式,可以設(shè)置其required屬性為false。另外一個比較重要的點就是,@Autowired注解默認按照類型裝配,如果容器中包含多個同一類型的Bean,那么啟動容器時會報找不到指定類型bean的異常,解決辦法是結(jié)合@Qualified注解進行限定,指定注入的bean名稱
@Resource注解
對于@Resource注解,它并不屬于spring的注解,而是來自于JSR-250。其默認情況下按照bean的名稱進行注入,當(dāng)找不到匹配項時會按照類型裝配。當(dāng)按照名稱進行裝配時,可以指定其name屬性,倘若沒有指定,注解標(biāo)注在哪個字段上,其默認名稱就是那個字段的名稱。當(dāng)然,@Resource注解也支持按指定類型進行裝配,給它的type屬性賦特定類型的值即可(注意,當(dāng)指定了name屬性后,只能按照名稱裝配)
public class SpringAnotationDemo {
@Bean
@Qualifier("httpApiClient")
public HttpApiClient createHttpClient() {
return new HttpApiClient();
}
@Resource(name = "httpApiClient")
private HttpApiClient httpApiClient;
@Resource(type = XQSmsHttpClient.class)
private SmsHttpClient smsHttpClient;
}
依我個人理解,其實@Resource要比@Autowired好用得多,@Resource注解的使用性更為靈活,可指定名稱,也可以指定類型 ,而用@Autowired注解進行裝配容易拋出異常,特別是裝配的bean類型有多個的時候,而解決的辦法是需要在增加@Qualitied進行限定
vc模塊注解">3、spring MVC模塊注解
web模塊常用到的注解包括:
@Controller、@RequestMapping、@RequestParam、@PathVariable
@Controller
將一個類加上@Controller注解后,表明該類會作為與前端作交互的控制層組件
@Controller
public class CompanyController {
/**this class will be the controller component of container**/
...
}
@RequestMapping
這個注解用于將url映射到整個處理類或者特定的處理請求的方法
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
...
}
如上例,當(dāng)標(biāo)注在class上時,表明此類會接收url為”/company”請求
@RequestParam
用于綁定request請求參數(shù)到指定的方法
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
@RequestMapping("/companyList")
public String listCompanies(Map<string, object=""> map,
@RequestParam(value = "data", required = false) String data,
@RequestParam(value = "phone_num", required = true) String phoneNum) {
map.put("data", data);
map.put("phoneNum", phoneNum);
return "companyList";
}
...
}
譬如上例中,@RequestParam請求參數(shù)指定了傳入?yún)?shù)的具體字段名(value指定的),以及是否必須傳的字段(默認情況下,required=true)。data,phoneNum為形參,即請求參數(shù)的使用名,可以更改
@PathVariable
該注解用于方法修飾方法參數(shù),會將修飾的方法參數(shù)變?yōu)榭晒┦褂玫膗ri變量(可用于動態(tài)綁定),請看如下栗子:
@Controller
@RequestMapping("/company")
public class CompanyController {
@Autowired
private CompanyService companyService;
@RequestMapping("{companyName}")
public String getCompany(Map<string, object=""> map,
@PathVariable String companyName) {
Company company = companyService.findByName(companyName);
map.put("company", company);
return "company";
}
...
}
當(dāng)我們請求 “/compony/account”時,componyName會動態(tài)地綁定為”account”
4、事務(wù)模塊注解@Transactional
在處理dao層或service層的事務(wù)操作時,譬如刪除失敗時的回滾操作,可用到@Transactional注解,如下例:
@Service
public class CompanyServiceImpl implements CompanyService {
@Autowired
private CompanyDAO companyDAO;
@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
public int deleteByName(String name) {
int result = companyDAO.deleteByName(name);
return company;
}
...
}
上例表明,執(zhí)行deleteByName方法時,啟用了事務(wù)處理,事務(wù)的各屬性含義如下:
propagation
事務(wù)的傳播行為,spring在TransactionDefinition接口中規(guī)定了7種類型的事務(wù)傳播行為,它們規(guī)定了事務(wù)方法和事務(wù)方法發(fā)生嵌套調(diào)用時如何進行傳播:
| 事務(wù)傳播行為類型 | 描述 |
|---|---|
| PROPAGATION_REQUIRED | 如果當(dāng)前沒有事務(wù),就新建一個事務(wù),如果已經(jīng)存在一個事務(wù)中,加入到這個事務(wù)中。這是最常見的選擇。 |
| PROPAGATION_SUPPORTS | 支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行。 |
| PROPAGATION_MANDATORY | 使用當(dāng)前的事務(wù),如果當(dāng)前沒有事務(wù),就拋出異常。 |
| PROPAGATION_REQUIRES_NEW | 新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。 |
| PROPAGATION_NOT_SUPPORTED | 以非事務(wù)方式執(zhí)行操作,如果當(dāng)前存在事務(wù),就把當(dāng)前事務(wù)掛起。 |
| PROPAGATION_NEVER | 以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則拋出異常 |
| PROPAGATION_NESTED | 如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。如果當(dāng)前沒有事務(wù),則執(zhí)行與PROPAGATION_REQUIRED類 似的操作 |
注:第一種是最常用的,默認的
readOnly
事務(wù)的讀寫屬性,取true或者false,true為只讀、默認為false rollbackFor
回滾策略,當(dāng)遇到指定異常時回滾。譬如上例遇到異常就回滾 timeout (補充的)
設(shè)置超時時間,單位為秒 isolation
設(shè)置事務(wù)隔離級別,枚舉類型,一共五種
| 類型 | 描述 |
|---|---|
| DEFAULT | 采用數(shù)據(jù)庫默認隔離級別 |
| READ_UNCOMMITTED | 讀未提交的數(shù)據(jù)(會出現(xiàn)臟讀?。?/td> |
| READ_COMMITTED | 讀已提交的數(shù)據(jù)(會出現(xiàn)幻讀,即前后兩次讀的不一樣) |
| REPEATABLE_READ | 可重復(fù)讀,會出現(xiàn)幻讀 |
| SERIALIZABLE | 串行化(對資源消耗較大,一般不使用) |
5、 Spring AOP模塊注解
spring aop模塊的注解主要有@Aspect、@Pointcut、@Before、@Around、@After、
@AfterReturning、@AfterThrowing
@Aspect
標(biāo)明該類為切面類,并啟用AspectJ注解,注:在使用時要同@Component一起使用,否則不會被掃描到加入容器
@Pointcut
定義切入點,關(guān)于切入點表達式書寫方式,請移步官方文檔:spring AOP文檔
@Around
定義環(huán)繞通知,在目標(biāo)方法執(zhí)行前后嵌入相關(guān)業(yè)務(wù)邏輯
@Before
定義前置通知,在目標(biāo)方法執(zhí)行前執(zhí)行
@After
定義后置通知,在目標(biāo)方法執(zhí)行后執(zhí)行,不論是目標(biāo)方法執(zhí)行正常后退出,還是拋出異常后退出,均會被執(zhí)行
@AfterReturning
目標(biāo)方法執(zhí)行正常退出后執(zhí)行 @AfterThrowing
目標(biāo)方法執(zhí)行拋出異常后執(zhí)行
總結(jié)
以上就是本文關(guān)于淺談spring 常用注解的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱:
有什么問題可以隨時留言,小編會及時回復(fù)大家的。感謝朋友們對本站的支持!
相關(guān)文章
MAC配置java+jmeter環(huán)境變量過程解析
這篇文章主要介紹了MAC配置java+jmeter環(huán)境變量過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09
Spring中的FactoryBean與BeanFactory詳細解析
這篇文章主要介紹了Spring中的FactoryBean與BeanFactory詳細解析,在Spring框架中,FactoryBean和BeanFactory是兩個關(guān)鍵的接口,用于創(chuàng)建和管理對象實例,它們在Spring的IoC(Inversion of Control,控制反轉(zhuǎn))容器中發(fā)揮著重要的作用,需要的朋友可以參考下2023-11-11
詳解mybatis多對一關(guān)聯(lián)查詢的方式
這篇文章主要給大家介紹了關(guān)于mybatis多對一關(guān)聯(lián)查詢的相關(guān)資料,文中將關(guān)聯(lián)方式以及配置方式介紹的很詳細,需要的朋友可以參考下2021-06-06

