Spring中常用注解的介绍

时间:2021-07-18 20:38:13

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>  
配置项就配置了对指定的包进行扫描,以实现依赖注入。
- @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模板中的变量作为参数。