引言
今天在搭建一个系统的基础框架的时候,发现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.youkuaiyun.com/songxingfeng/article/details/7882197
[4]http://blog.youkuaiyun.com/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