Spring中常用注解的介绍
spring中使用注解时配置文件的写法:
<?xml version="1.0" encoding="UTF-8"?>
<span style="font-size:18px;"><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<aop:aspectj-autoproxy/>
<context:annotation-config/>
<context:component-scan base-package="com.test" />
</beans>
<context:component-scan />配置项就配置了对指定的包进行扫描,以实现依赖注入。
- @Controller
- @Service
- @Autowired
- @RequestMapping
- @RequestParam
- @ModelAttribute
- @Cacheable
- @CacheFlush
- @Resource
- @PostConstruct
- @PreDestroy
- @Repository
- @Component
- @Scope
- @SessionAttributes
- @InitBinder
- @Required
- @Qualifier
下面介绍下一些常见注解的使用:
@Autowired
private IReportService reportService ;
@Autowired
Spring2.5引入了 @Autowired
注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。另外,通过 @Autowired
可以消除get,set方法。 @Autowired
是根据类型进行自动转配的。
这里要注意 @Resource
也可以实现自动装配,但是 @Resource
默认是按照名称进行自动装配。
@Autowired 根据bean 类型从spring 上线文中进行查找,注册类型必须唯一,否则报异常。与 @Resource 的区别在于,@Resource 允许通过bean 名称或bean 类型两种方式进行查找 @Autowired(required=false) 表示,如果spring 上下文中没有找到该类型的bean 时, 才会使用new SoftPMServiceImpl();
@Autowired 标注作用于 Map 类型时,如果 Map 的 key 为 String 类型,则 Spring 会将容器中所有类型符合 Map 的 value 对应的类型的 Bean 增加进来,用 Bean 的 id 或 name 作为 Map 的 key。
@Autowired 还有一个作用就是,如果将其标注在 BeanFactory 类型、ApplicationContext 类型、ResourceLoader 类型、ApplicationEventPublisher 类型、MessageSource 类型上,那么 Spring 会自动注入这些实现类的实例,不需要额外的操作。
这里简单介绍下什么是按类型进行装配,什么是按名称进行装配?
所谓按类型,就是当Spring容器中存在一个与指定属性类型相同的bean,那么将该属性进行自动装配;如果存在多个该类型的bean,那么跑出异常,并指出不能使用按类型进行自动装配;如果没有找到匹配的bean,则什么事都不发生。
所谓按名称,即根据属性名进行自动装配,此项会检查Spring容器中与该属性名完全一致的的bean,进行自动装配。
@Qualifier
@Autowired
@Qualifier("softService")
private ISoftPMService softPMService;
使用 @Autowired时,如果找到多个同一类型的bean,则会抛异常,此时可以使用 @Qualifier("beanName"),明确指定bean的名称进行注入,此时与 @Resource指定name属性作用相同。
@Component
@Component("reportAction")
@Scope("request")
public class ReportAction extends AbstractBaseAction
下面的解释来自官方文档
@Repository
、@Service
和 @Controller
。
@Component
是所有受Spring管理组件的通用形式;
而 @Repository
、@Service
和 @Controller
则是 @Component
的细化, 用来表示更具体的用例(例如,分别对应了持久化层、服务层和表现层)。 也就是说, 你能用 @Component
来注解你的组件类,
但如果用 @Repository
、@Service
或 @Controller
来注解它们,你的类也许能更好地被工具处理,或与切面进行关联。
例如,这些典型化注解可以成为理想的切入点目标。当然,在Spring Framework以后的版本中,@Repository
、@Service
和 @Controller
也许还能携带更多语义。如此一来,如果你正在考虑服务层中是该用 @Component
还是 @Service
,
那 @Service
显然是更好的选择。同样的,就像前面说的那样,@Repository
已经能在持久化层中进行异常转换时被作为标记使用了。
@Controller
<!--方式一--在SpringMVC 的配置文件中定义MyController 的bean 对象-->
<bean class="com.host.app.web.controller.MyController"/>
<!--方式二--在SpringMVC 的配置文件中告诉Spring 该到哪里去找标记为@Controller 的Controller 控制器。-->
< context:component-scan base-package = "com.host.app.web" />//路径写到controller的上一层
在SpringMVC 中,控制器Controller负责处理由DispatcherServlet分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model,然后再把该Model返回给对应的View进行展示。在SpringMVC中提供了一个非常简便的定义Controller的方法,你无需继承特定的类或实现特定的接口,只需使用 @Controller标记一个类是Controller,然后使用 @RequestMapping和 @RequestParam等一些注解用以定义URL请求和Controller方法之间的映射,这样的Controller就能被外界访问到。此外Controller不会直接依赖于HttpServletRequest 和HttpServletResponse等HttpServlet对象,它们可以通过Controller的方法参数灵活的获取到。
@Service
@Service
public class SoftCreateServiceImpl implements ISoftCreateService {}
//或者
@Service("softCreateServiceImpl")
@Service 负责注册一个bean 到spring 上下文中,bean 的ID 默认为类名称开头字母小写
@Repository
与 @Controller 、 @Service 类似,都是向spring 上下文中注册bean。
@Resource
@Resource
private DataSource dataSource; // inject the bean named 'dataSource'
@Resource(name="dataSource")
@Resource(type=DataSource.class)
@Resource 默认按bean的name进行查找,如果没有找到会按type进行查找,此时与 @Autowired类似。
在没有为 @Resource 注解显式指定 name 属性的前提下,如果将其标注在BeanFactory类型、ApplicationContext类型、ResourceLoader类型、ApplicationEventPublisher类型、MessageSource 类型上,那么 Spring 会自动注入这些实现类的实例,不需要额外的操作。此时 name 属性不需要指定 ( 或者指定为""),否则注入失败;
@RequestMapping
@Controller
@RequestMapping("/bbtForum.do")
public class BbtForumController {
@RequestMapping(params = "method=listBoardTopic")
public String listBoardTopic(int topicId,User user) {}
}
@RequestMapping("/softpg/downSoftPg.do")
@RequestMapping(value="/softpg/ajaxLoadSoftId.do", method=RequestMethod.POST)
@RequestMapping(value="/osu/product/detail.do", params={"modify=false"}, method=RequestMethod.POST)
@RequestMapping 可以声明到类或方法上
参数绑定说明
如果我们使用以下的 URL 请求:
http://localhost/bbtForum.do?method=listBoardTopic&topicId=1&userId=10&userName=tom
topicId URL参数将绑定到 topicId入参上,而userId和 userName URL参数将绑定到user对象的userId和userName属性中。和URL请求中不允许没有topicId参数不同,虽然User的userId属性的类型是基本数据类型,但如果URL中不存在userId参数,Spring也不会报错,此时user.userId值为0 。如果User对象拥有一个dept.deptId 的级联属性,那么它将和dept.deptId URL参数绑定。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明(下面有相应示例)。
1、 value, method;
value:指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
method:指定请求的method类型,GET、POST、PUT、DELETE等;
2、consumes,produces
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3、params,headers
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
@RequestParam
@RequestParam("id")
@RequestParam(required=false) //参数不是必须的,默认为true
@RequestParam(value="id",required=false)
http://localhost/bbtForum.do?method=listBoardTopic&id=1&userId=10&userName=tom
listBoardTopic(@RequestParam("id")int topicId,User user) 中的 topicId 绑定到 id 这个 URL 参数, 那么可以通过对入参使用 @RequestParam 注解来达到目的
@Scope
@Scope("session")
@Repository()
public class UserSessionBean implementsSerializable {}
在使用XML定义Bean时,可以通过bean的scope属性来定义一个Bean的作用范围,同样可以通过 @scope注解来完成。
@Scope中可以指定如下值:
- singleton:定义bean的范围为每个spring容器一个实例(默认值)
- prototype:定义bean可以被多次实例化(使用一次就创建一次)
- request: 定义bean的范围是http请求(springMVC中有效)
- session: 定义bean的范围是http会话(springMVC中有效)
- global-session:定义bean的范围是全局http会话(portlet中有效)
@SessionAttributes
@SessionAttributes("currUser") // 将ModelMap 中属性名为currUser 的属性
@SessionAttributes({"attr1","attr2"})
@SessionAttributes(types = User.class)
@SessionAttributes(types = {User.class,Dept.class})
@SessionAttributes(types = {User.class,Dept.class},value={"attr1","attr2"})
Spring 允许我们有选择地指定 ModelMap 中的哪些属性需要转存到 session 中,
以便下一个请求属对应的 ModelMap 的属性列表中还能访问到这些属性。
这一功能是通过类定义处标注 @SessionAttributes 注解来实现的。
@SessionAttributes 只能声明在类上,而不能声明在方法上。
@Controller
@RequestMapping("/bbtForum.do")
@SessionAttributes("currUser") //@1将ModelMap中属性名为currUser的属性
//放到Session属性列表中,以便这个属性可以跨请求访问</span>
public class BbtForumController {
…
@RequestMapping(params = "method=listBoardTopic")
public String listBoardTopic(@RequestParam("id")int topicId, User user,
ModelMap model) {
bbtForumService.getBoardTopics(topicId);
model.addAttribute("currUser",user);//@2向ModelMap中添加一个属性</span>
return "listTopic";
}
}
我们在 @2处添加了一个 ModelMap 属性,其属性名为 currUser,而 @1处通过 @SessionAttributes 注解将 ModelMap 中名为 currUser 的属性放置到 Session 中,所以我们不但可以在 listBoardTopic() 请求所对应的 JSP 视图页面中通过 request.getAttribute(“currUser”) 和 session.getAttribute(“currUser”) 获取 user 对象,还可以在下一个请求所对应的 JSP 视图页面中通过 session.getAttribute(“currUser”) 或 ModelMap#get(“currUser”) 访问到这个属性。
@ModelAttribute
@Controller
@SessionAttributes("currentUser")
public class GreetingController{
@RequestMapping
public void hello(@ModelAttribute("currentUser") User user){
//user.sayHello()
}
}
我们可以在需要访问Session属性的controller上加上 @SessionAttributes,然后在action需要的User参数上加上 @ModelAttribute,并保证两者的属性名称一致。SpringMVC就会自动将 @SessionAttributes定义的属性注入到ModelMap对象,在setup action的参数列表时,去ModelMap中取到这样的对象,再添加到参数列表。只要我们不去调用SessionStatus的setComplete()方法,这个对象就会一直保留在Session中,从而实现Session信息的共享。
@Required
@Required
public setName (String name) {}
@Required负责检查一个bean在初始化时其声明的set方法是否被执行,当某个被标注了 @Required的Setter方法没有被调用,则Spring在解析的时候会抛出异常,以提醒开发者对相应属性进行设置。@Required注解只能标注在Setter方法之上。因为依赖注入的本质是检查Setter方法是否被调用了,而不是真的去检查属性是否赋值了以及赋了什么样的值。如果将该注解标注在非setXxxx()类型的方法则被忽略。
@PostConstruct
在方法上加上注解 @PostConstruct,这个方法就会在Bean初始化之后被Spring容器执行(注:Bean 初始化包括,实例化Bean,并装配Bean的属性(依赖注入))。
@PreDestroy
在方法上加上注解 @PreDestroy ,这个方法就会在Bean 被销毁前被Spring 容器执行。
@PathVariable
@Controller
public class TestController {
@RequestMapping(value="/user/{userId}/roles/{roleId}",method = RequestMethod.GET)
public String getLogin(@PathVariable("userId") String userId,
@PathVariable("roleId") String roleId){
System.out.println("User Id : " + userId);
System.out.println("Role Id : " + roleId);
return "hello";
}
}
用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。