引言
今天在搭建一個系統的基礎框架的時候,發現Spring的註解好久沒複習了,導致很多問題都需要藉助度娘,好吧,把常用的整理一下,方便以後複習!
注意:如果使用Java8那麼就不要再嘗試使用Spring4以前的版本了,無法執行。
請看參考文章[6]
使註解工作
很簡單,只需要在配置文件中,設置組件搜索範圍就可以加載帶有註解的class了。
以前我實現了一個簡單的web框架也是用這種方式實現的。
<context:component-scan base-package="org.tornado.spring.test.service" />
@Autowired 和@Resource
二者作用基本一致。
只不過@Autowired
通過類型進行匹配(byType)。這個很好理解。
@Autowired
private UserDao userDao;
就是通過UserDao
的類型進行匹配。如果有加載成功,如果沒有加載失敗!
蛋疼的時候聲明瞭兩個UserDao,咋辦?用這個註解:@Qualifier("bean id")
,通過這個進行區分。
使用方法如下:
用在方法上:
@Autowired
public void setOffice(@Qualifier("office")Office office) {
this.office = office;
}
用在屬性上:
@Autowired
@Qualifier("office")
private Office office;
@Resource功能更強大些。
沒有指定任何參數的時候搜索順序是:
首先根據變量的名稱進行查找(byName);
如果沒有找到在通過變量的類型進行查找(byType)。
例如:
@Resource
private UserDao myUserDao;
首先根據變量的名稱“myUserDao”進行查找,如果找到直接加載。
如果沒有就通過UserDao的類型進行匹配。
另外還可以通過指定名稱和類型的方式進行加載。
byName
@Resource(name="userDao")
private UserDao myUserDao;
byType
@Resource(type=UserDao.class)
private UserDao myUserDao;
如果有set方法,一般建議將這兩個註解用到方法上。
@PostConstruct
這個註解說明這個函數在bean執行實例化後自動執行。
@PostConstruct
public void init()
{
System.out.println("執行init method");
}
關於Class的註解
註解有四個,基本上一樣。很多人都建議不要使用@Component
,因爲這樣語義不清。
目前4.3的版本上這四個定義的方式目前都是一樣的。
按照“聽人勸,吃飽飯!”的指導原則,分着用,是目前最好的實踐方式!
註解 | 說明 |
---|---|
@Repository | 表示持久層 |
@Service | 表示業務層 |
@Controller | 表示展示層 |
堅持這種規範的命名那就不要再使用@Component了。
關於@Scope
這個註解使用的也是挺多的,特別是在用Spring-MVC的時候。
目前4.3的源碼中Doc如下
Defaults to an empty string ({@code ""}) which implies
{@link ConfigurableBeanFactory#SCOPE_SINGLETON SCOPE_SINGLETON}.
@since 4.2
@see ConfigurableBeanFactory#SCOPE_PROTOTYPE
@see ConfigurableBeanFactory#SCOPE_SINGLETON
@see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST
@see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION
不詳細翻譯,大致的意思如下:
默認的@Scope
範圍是ConfigurableBeanFactory.SCOPE_SINGLETON
也就是單例;
可的範圍有以下幾種ConfigurableBeanFactory.SCOPE_PROTOTYPE
等。
其中:SCOPE_SINGLETON
,SCOPE_PROTOTYPE
是面向全部應用的的。
其他主要是針對web應用的。
對於web的變量建議使用其他的表示形式。
Spring-mvc的4.3版本中已經添加了3個關於Scope
的註解。(什麼時候開始的不清楚)。
以下表格左側和右側是等價的。建議使用左側。
獨立註解 | @Scope註解 |
---|---|
@ApplicationScope | @Scope(WebApplicationContext.SCOPE_APPLICATION) |
@RequestScope | @Scope(WebApplicationContext.SCOPE_REQUEST) |
@SessionScope | @Scope(WebApplicationContext.SCOPE_SESSION) |
沒有 | @Scope(WebApplicationContext.SCOPE_GLOBAL_SESSION) |
關於各個@Scope
註解的說明:
註解名稱 | 作用範圍 |
---|---|
Singleton | 單例,當前應用只有一個實例 |
Property | 每次獲取Class對象的時候都需要創建一個實例 |
Request | 對於一次Request的請求,容器就會創建一個實例。請求結束實例銷燬。 |
Session | 在Http的Session週期只會創建一個實例,Session失效,實例銷燬。 |
GlobalSession | 這個週期是在Portlet應用中使用的,整個Portlet容器共享一個用戶的會話,表示在這個週期裏只創建一個對象 |
Application | 應用的全部週期只會創建一個實例,這個和Singleton非常像。感覺可以互換。 |
待確定的問題:
4.3以後的版本,web應用@Scope貌似不需要Listener和Filter就可以生效了!
參考文章:
[1]https://my.oschina.net/u/216467/blog/205951
[2]http://www.jb51.net/article/75460.htm
[3]http://blog.csdn.net/songxingfeng/article/details/7882197
[4]http://blog.csdn.net/cdl2008sky/article/details/6265742
[5]http://stackoverflow.com/questions/15407038/spring-bean-scopes-session-and-globalsession
[6]https://www.infoq.com/articles/spring-4-java-8