Spring常用注解说明
- Spring常用注解说明
- 用于对象的注解-IOC相关注解
- @Scope用于设置对象的生命周期注解
- @PostConstruct @PreDestroy初始化和销毁方法注解
- 用于依赖注入的注解
- @Autowired注解
- 在字段上面注入
- 在方法上面注入
- 在构造方法上面注入
- @Qualifier注解
- @Resource注解
- 依赖注入注解所在的包的位置
- @Value注解
- 案例代码
Spring常用注解说明
用于对象的注解-IOC相关注解
我们将用于被扫描创建对象的注解,统称为组件注解。
组件包括:@Component,@Controller,@Service,@Repository。
组件注解的功能都是标识类为注解的组件类,启动Spring框架的程序时,声明将这些组件类注入到Spring容器里面。意味着,只有加了这四个注解任何一个注解的类,在程序启动的时候,Spring就通过配置文件指定的路径将该路径下的所有带组件注解的类创建对象并且放在容器里面。
功能类似原来配置文件的<bean>标签
问题:明明一个@Component注解就可以满足了扫描的需要,为什么要有四个呢?
答:其实Spring第一版注解的实现(spring 2.5),就是使用一个@Component。从3.0以后,作者认为根据分层的需要,把它拆成了四个。为了可以让开发人员,可见即可得,一看到注解,立即知道类的性质。所以分成了四个
@Controller:用于声明表示层的组件注解
@Service:用于声明服务层的组件注解
@Repository:用于声明持久层的组件注解
@Component:用于声明三层以外的组件注解
问题:那么,这四个注解交换使用会报错吗。如:持久层,我放@Service标记。
答:处理@Controller在**SpringMVC里面有强制的要求,SpringMVC的表示层必须使用@Controller组件注解。其他情况,用乱了是不会报错的,不过我们必须不能用乱。不遵守规范,不然别人无法跟你一起开发了。
@Scope用于设置对象的生命周期注解
Xml配置需要配置对象的作用范围
<bean id="someBean" class="..." scope="作用范围"></bean>
如果使用注解配置bean,那么bean的作用范围也需要使用注解配置
@Scope(“作用范围”)
singleton | 单例 ,在Spring IoC容器中仅存在一个Bean实例 (默认的scope) |
prototype | 多例 ,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时 ,相当于执行new XxxBean(): |
request | 用于web开发,将Bean放入request范围 ,request.setAttribute(“xxx”) , 在同一个request 获得同一个Bean |
session | 用于web开发,将Bean 放入Session范围,在同一个Session 获得同一个Bean |
package cn.xc.spring.controller;
import javax.annotation.Resource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.xc.spring.service.CustomerService;
@Controller("customerController")
@Scope("prototype")
public class CustomerController {
//直接字段注入,不需要setter方法
//@Resource //按照类型注入
@Resource(name="customerService")//类型+id
private CustomerService customerService;
public void save() {
//调用服务的save方法
customerService.save();
}
}
在开发中主要使用 scope=“singleton”、 scope=“prototype”
对于MVC中的Action/Controller使用prototype类型,其他使用singleton
@PostConstruct @PreDestroy初始化和销毁方法注解
在xml配置中可以配置对象的初始化方法和销毁方法
<bean id="someBean" class="cn.xc.spring.domain.SomeBean"
init-method="init"
destroy-method="destory"></bean>
如果使用注解配置bean,那么bean的作用范围也需要使用注解配置
@PostConstruct // 相当于<bean init-method="init" />
public void init() {
System.out.println("初始化方法执行了");
}
@PreDestroy// 相当于<bean destroy-method="destory" />
public void destory() {
System.out.println("销毁方法执行了");
}
用于依赖注入的注解
回顾:XML配置文件使用<property name=”” ref=””>实现注入的。通过注入注解也可以实现。
Spring提供了两套注解可以解决依对象依赖注入的方案
1,@Autowired +@Qualifier():是Spring定义的标签
2,@Resouce:是JavaEE的规范
@Autowired注解
@Autowired注解:用于给引用注入容器的对象。
- @Autowired标签贴在字段或者setter方法上
- 默认情况下@Autowired标签必须要能找到对应的对象,否则报错。不过,可使用required=false来避免该问题:@Autowired(required=false)
- @Autowired找bean的方式:
(1) 首先按照依赖对象的类型找,如果找到则使用setter方法或者字段直接注入;
(2) 如果在Spring上下文中找到多个匹配的类型,再按照名字去找,如果没有匹配则报错;
(3) 可以通过使用@Qualifier(“otherBean”)标签来规定依赖对象按照bean的id+类型去找
使用@Autowired注入的三种情况
在字段上面注入
package cn.xc.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import cn.xc.spring.service.CustomerService;
//表示层使用@Controller
//如果组件注解不声明对象名,默认使用默认命名法,
//所谓的默认命名就是,将类的首字符小写作为类的对象名
//组件注解
//属性 value:作用用于指定该类对象的自定义对象名
@Controller("customerController")
public class CustomerController {
//直接字段注入,不需要setter方法
@Autowired
private CustomerService customerService;
/*public void setCustomerService(CustomerService customerService) {
this.customerService = customerService;
}*/
public void save() {
//调用服务的save方法
customerService.save();
}
}
在方法上面注入
package cn.xc.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import cn.xc.spring.service.CustomerService;
//表示层使用@Controller
//如果组件注解不声明对象名,默认使用默认命名法,
//所谓的默认命名就是,将类的首字符小写作为类的对象名
//组件注解
//属性 value:作用用于指定该类对象的自定义对象名
@Controller(value="customerController")
public class CustomerController {
private CustomerService customerService=null;
//注意,如果将@Autowired方法方法上面,意思就是将对象注入到该的方法的参数
//意味着:Spring会自动根据参数的CustomerService类型匹配容器中对应的对象给它
//注意:能够使用@Autowired注解的方法是必须有参数的
@Autowired
public void setCustomerService(CustomerService customerService) {
//问题:加了@Autowired的方法在启动的时候是否执行了?
//答:如果该方法没有执行,那么this.customerService的对象从哪里来呢?
//加了@Autowired在启动项目的时候是必须自动执行的
System.out.println("-setCustomerService已经被执行-");
this.customerService = customerService;
}
public void save(){
System.out.println("-保存客户-CustomerAction");
customerService.save();
}
}
在构造方法上面注入
package cn.xc.spring.controller;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import cn.xc.spring.service.CustomService;
@Controller
public class CustomController {
private CustomService service;
/*
* 方式三 : 构造器注入
* 使用注解的IOC创建bean的情况下
* 默认bean中有什么样的构造器,spring就调用那个构造器去创建对应的bean对象
* 并且会自动注入 构造器中对应类型参数的对象
*
* 问题: 如果构造函数的参数类型对应的bean有多个,会抛出异常
* org.springframework.beans.factory.NoUniqueBeanDefinitionException 不是唯一的bean异常
* 解决方案: 在参数前面 使用 @Qualifier("service1") 注解
* 从多个bean 获取指定 id 对应的bean即可
*/
public CustomController(@Qualifier("service1") CustomService service) {
this.service = service;
}
public void save() {
service.save();
}
}
@Qualifier注解
@Qualifier注解:用于指定注入的对象名,使用@Autowired注入对象时,@Autowired没有指定对象名的属性,只能通过@Qualifier字段容器中对象名
属性
value:指定注入Spring容器中对应对象名的对象给引用。
@Controller("customerController")
public class CustomerController {
//直接字段注入,不需要setter方法
@Autowired
@Qualifier(value="customerService")
private CustomerService customerService;
public void save() {
//调用服务的save方法
customerService.save();
}
}
@Resource注解
@Resource注解是Spring框架支持Sun官方制定的JSR-250标准注入对象的实现。
JSR-250就是Sun公司制定,对注入的对象的标准。
@Resource 功能等同 @Autowired + @Qualifier ,等同配置文件标签 <proprty name=”…” ref=”…”>
@Resource注解:用于给引用注入容器的对象,可以通过name属性指定对象名
注意事项:@Resource只能使用字段和setter方法,不能注入构造方法
package cn.xc.spring.controller;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import cn.xc.spring.service.CustomerService;
@Controller("customerController")
public class CustomerController {
//直接字段注入,不需要setter方法
//@Resource //按照类型注入
@Resource(name="customerService")//类型+id
private CustomerService customerService;
public void save() {
//调用服务的save方法
customerService.save();
}
}
依赖注入注解所在的包的位置
除了@Resource注解是Java官方的标准,内置在JDK里面以外,Spring内置实现的注解声明放在spring-beans-5.0.5.RELEASE.jar里面。如下图所示:
@Value注解
<value>
//value只能设置,标量类型=基础数据类型+包装类+String
@Value注解:注入基本数据类型以及它们的包装类和String类型数据的,支持${}注入Properties文件的键值对,等同 <proprty name=”…” value=”${Key}”>。
属性:
value:注入基本数据类型和String类型数据的
案例代码
package cn.xc.spring.dao.impl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
import cn.xc.spring.dao.UserDao;
import cn.xc.spring.pojo.User;
@Repository
public class UserDaoImpl implements UserDao {
/**
* @Value(value="")
* 可以从Spring容器读取 .properties 配置文件内容
* value :配置文件的对应的key -->使用 ${key} 获取
* 程序运行中自动将 properties 对应key的获取出来设置给字段
*
*/
//等价 <property name="driverClassName" value="${jdbc.driverClassName}">
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//@Value("${jdbc.maxActive}")
@Value("100") //开发者也手动赋值
private String maxActive;
@Override
public void insert(User user) {
System.out.println(driverClassName);
System.out.println(url);
System.out.println(username);
System.out.println(password);
System.out.println(maxActive);
}
}