本文持续更新SpringBoot会用到的注解知识。
SpringBoot注解
注解集成了许多功能,不仅可以简化代码编写,同时方便阅读。
@EnableAsync和 @Async(异步执行)
注意:两个标签要配合使用
- 在启动类上加上 @EnableAsync 注解开启项目的异步调用功能;
- 在需异步调用的方法上加上注解 @Async 即可实现方法的异步调用。
启动类:
@EnableAsync
@SpringBootApplication
@EnableTransactionManagement
@MapperScan("cc.mrbird.febs.*.mapper")
public class FebsApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(FebsApplication.class).run(args);
}
}
异步方法:
@Async(FebsConstant.ASYNC_POOL)
void saveLog(ProceedingJoinPoint point, Method method, String ip, String operation, long start);
注意:调用异步方法时,不要直接提取异步方法返回值并向上返回。因为,异步方法启动执行之后,当前方法会继续向后执行,不会等待返回,所以此时还没有异步方法返回值,提取无效。
具体使用方法可参考: 举例.
@Controller(页面刷新,返回整体页面)
整体页面刷新提交的处理注解,返回的是页面。
例如:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* Created by Administrator on 2018/6/24.
*/
@Controller
@RequestMapping("/freemarker")
public class HelloWorldFreemakerController {
/**
* 设置数据,返回到freemarker视图
* @return
*/
@RequestMapping("/say")
public ModelAndView say(){
ModelAndView mav=new ModelAndView();
mav.addObject("message", "SpringBoot 好厉害!");
mav.setViewName("helloWorld"); //对应helloWorld.ftl
return mav;
}
}
# helloWorld.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
show:${message}
</body>
</html>
可参考连接.
@ResponseBody(方法结果(数据)返回到页面,并在页面显示)
表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用,用于构建RESTful的api(将方法的返回值发送到页面)。
例如:
@ResponseBody
@RequestMapping("/freemarker")
public class HelloWorldFreemakerController {
@RequestMapping("/add")
public String addUser(UserDomain user){
System.out.println("进入controoler........"+user.getUserName());
int flag=userService.addUser(user);
System.out.println("controller返回状态........"+flag);
return "添加成功!!!,返回状态:"+flag+"";
}
}
最后,“添加成功!!!,返回状态:”+flag+""将返回给页面,页面也将显示这个值。
@RestController(页面局部刷新,返回json格式)
局部刷新,或者叫做异步刷新,ajax提交,一般返回json格式,相当于我们经常使用的@ResponseBody配合@Controller组合。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 返回ajax json格式
* @author user
*
*/
@RestController
@RequestMapping("/ajax")
public class HelloWorldAjaxController {
@RequestMapping("/hello")
public String say(){
return "{'message1': 'SpringBoot 好厉害','message2','SpringBoot 真厉害'}";
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="jQuery.js"></script>
<script type="text/javascript">
function show(){
$.post("ajax/hello",{},
function(result){
alert(result);
}
);
}
</script>
</head>
<body>
<button onclick="show()">厉害</button>
</body>
</html>
可参考连接.
@Service(业务层Bean)
用于业务层Bean类前。
例如,实现接口UserService,定义UserServiceImpl实现类。同时设置该实现类的 @Service 注解名称为userService:
@Service("userService")
public class UserServiceImpl implements UserService {
………
}
@Service(“userService”)注解是告诉SpringBoot,当SpringBoot要创建 UserServiceImpl 的实例时,bean的名字必须为 “userService”。这样,当 Action 需要使用 UserServiceImpl 的实例时,就可以由SpringBoot创建好"userService",然后注入给Action,代码如下:
@Resource(name = "userService")
private UserService userService;
注意:
- 在Action声明的“userService”变量的类型必须是“UserServiceImpl”或者是其父类“UserService”,否则由于类型不一致而无法注入;不用通过“UserService userService = new UserServiceImpl();”这种最原始的方式去实例化userService了。
- Action原来需要主动创建UserServiceImpl实例,现在SpringBoot可以自动创建。这说明Action对“UserServiceImpl”类的“控制权”已经被“反转”了——“控制反转”,也叫“依赖注入”(“依赖注入”可理解为:Action需要使用UserServiceImpl干活,那么就是对UserServiceImpl产生了依赖,SpringBoot把Acion需要依赖的UserServiceImpl注入到Action,这就是所谓的“依赖注入”。)
@Component(组件)
所有受 SpringBoot 管理的组件都可以用@Component注解。由于区分度低,不建议使用@Component。
@Repository(数据访问层Bean)
用于数据访问层Bean类前。
例如,实现接口BaseDaoImpl,定义UserDaoImpl实现类。同时设置该实现类的 @Service 注解名称为userDao:
@Repository(value="userDao")
public class UserDaoImpl extends BaseDaoImpl<User> {
………
}
@Repository(value=“userDao”)注解是告诉SpringBoot,让SpringBoot创建一个名字叫“userDao”的UserDaoImpl实例。
当Service需要使用SpringBoot创建的名字叫“userDao”的UserDaoImpl实例时,就可以使用@Resource(name = “userDao”)让SpringBoot把创建好的userDao注入给Service:
@Resource(name = "userDao")
private BaseDao<User> userDao;
@ComponentScan(组件扫描)
用于类或接口上,可自动扫描并加载符合条件的组件(比如@Controller、@Service、@Component、@Repository等)或者 bean 定义,最终将这些 bean 定义加载到IoC容器中。
1)可以通过 basePackages 、value等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的 package 进行扫描。所以SpringBoot的启动类最好是放在 root package 下,因为默认不指定basePackages。
2)basePackageClasses:指定具体扫描的类。
3)includeFilters:指定满足Filter条件的类。
4)excludeFilters:指定排除Filter条件的类。
includeFilters 和 excludeFilters 的 FilterType 可选:ANNOTATION=注解类型默认、ASSIGNABLE_TYPE(指定固定类)、ASPECTJ(ASPECTJ类型)、REGEX(正则表达式)、CUSTOM(自定义类型),自定义的 Filter 需要实现 TypeFilter 接口。
例如:
@ComponentScan(value="com.maple.learn",
excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class)},
includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class})})
public class SampleClass{
……
}
其他参数:
1)lazyInit:指定是否应注册扫描的beans为lazy初始化。
2)nameGenerator:用于在Spring容器中的检测到的组件命名。
3)resourcePattern:控制可用于组件检测的类文件。
4)scopedProxy:指出代理是否应该对检测元件产生,在使用过程中会在代理风格时尚的范围是必要的。
5)scopeResolver:用于解决检测到的组件的范围。
6)useDefaultFilters:指示是否自动检测类的注释
可参考连接.
@EnableAutoConfiguration (启动类注解)
借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
@EnableAutoConfiguration自动配置的逻辑是:从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。
详细实现源码解析,可参考:连接
@SpringBootConfiguration (启动类注解)
标注在类上,表示对配置类所有成员生效。是@Configuration注解的派生注解,跟@Configuration注解的功能一致,标注这个类是一个配置类,只不过@SpringBootConfiguration是springboot的注解,而@Configuration是spring的注解。
@Configuration:
需要实现Conditional接口:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition}s that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
接口实现:
public class MyCondition implements Condition {
/**
* ConditionContext:判断条件能使用的上下文(环境)
* AnnotatedTypeMetadata:注释信息
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 1、能获取到ioc使用的beanfactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 2、获取类加载器
ClassLoader classLoader = context.getClassLoader();
// 3、获取当前环境信息
Environment environment = context.getEnvironment();
// 取到运行环境的信息
String property = environment.getProperty("os.name");
// 4、获取到bean定义的注册类,可以查看类的定义信息,如是否单例,是否懒加载等,详细查看BeanDefinitionRegistry的接口定义
BeanDefinitionRegistry registry = context.getRegistry();
// 可以判断容器中的bean注册情况,也可以给容器中注册bean
boolean definition = registry.containsBeanDefinition("red");
// 根据实际的情况,判断接口,返回boolean值,就可以了
return true;
}
}
在类中使用:
@Conditional({ MyCondition.class })
@Configuration
public class MyConfig {
@Bean
@Conditional({ MyCondition.class })
public Date date() {
return new Date();
}
}
@Inherited (接口继承)
指明被注解的类会自动继承. 更具体地说,如果定义注解时使用了 @Inherited 标记,然后用定义的注解来标注另一个父类, 父类又有一个子类(subclass),则父类的所有属性将被继承到它的子类中。
注意:使用Inherited声明出来的注解,只有在类上使用时才会有效,对方法,属性等其他无效。
首先,定义你的注解:
@Inherited
public @interface MyParentObject {
boolean isInherited() default true;
String doSomething() default "Do what?";
}
接下来,使用注解标注了一个类:
@MyParentObject
public Class MyChildObject {
}
正如你看到的,你不需要在实现类中定义接口方法. 因为使用 @Inherited标记,这些都自动继承了. 如果你使用一种古老的方式定义实现类,会是什么样子呢? 看看下面这张 古老的实现方式吧:
public class MyChildObject implements MyParentObject {
public boolean isInherited() {
return false;
}
public String doSomething() {
return "";
}
public boolean equals(Object obj) {
return false;
}
public int hashCode() {
return 0;
}
public String toString() {
return "";
}
public Class annotationType() {
return null;
}
}
@Documented (文档化)
指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值。 如果一个类型声明被注释了文档化,它的注释成为公共API的一部分。
@Retention (生存周期)
注解用于指明修饰的注解的生存周期,即会保留到哪个阶段。
RetentionPolicy的取值包含以下三种:
1)SOURCE:源码级别保留,编译后即丢弃。
2)CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
3)RUNTIME:运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。
@Retention(RetentionPolicy.RUNTIME)
@Target (注解)
用于定义注解的使用位置,如果没有该项,表示注解可以用于任何地方。
@Target的ElementType取值有以下类型:
1)TYPE:类,接口或者枚举
2)FIELD:域,包含枚举常量
3)METHOD:方法
4)PARAMETER:参数
5)CONSTRUCTOR:构造方法
6)LOCAL_VARIABLE:局部变量
7)ANNOTATION_TYPE:注解类型
8)PACKAGE:包
// 单参数
@Target({ ElementType.METHOD })
// 多参数
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@SpringBootApplication (启动类注解)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
//自动注入的时候,排序的类
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
//自动注入的时候,排序的类的名字
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
//自动注入的时候,扫描的包路径
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
//自动注入的时候,扫描的类注解(@Service,@Controller等)
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
可参考: 连接.
@RequestMapping(请求映射)
用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。@RequestMapping用在类上可以没有,但是用在方法上必须有。
@RequestMapping是handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型)
1)处理request url 部分(这里指uri template中variable,不含queryString部分)的注解: @PathVariable;
2)处理request header部分的注解: @RequestHeader, @CookieValue;
3)处理request body部分的注解:@RequestParam, @RequestBody;
4)处理attribute类型是注解: @SessionAttributes, @ModelAttribute;
@RequestMapping注解有六个属性,下面我们把它分成三类进行说明
1、value: 指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
2、method: 指定请求的method类型, GET、POST、PUT、DELETE等;
@Controller
@RequestMapping("/appointments")
public class AppointmentsController {
private final AppointmentBook appointmentBook;
@Autowired
public AppointmentsController(AppointmentBook appointmentBook) {
this.appointmentBook = appointmentBook;
}
@RequestMapping(method = RequestMethod.GET)
public Map<String, Appointment> get() {
return appointmentBook.getAppointmentsForToday();
}
@RequestMapping(value="/{day}", method = RequestMethod.GET)
public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {
return appointmentBook.getAppointmentsForDay(day);
}
@RequestMapping(value="/new", method = RequestMethod.GET)
public AppointmentForm getNewForm() {
return new AppointmentForm();
}
@RequestMapping(method = RequestMethod.POST)
public String add(@Valid AppointmentForm appointment, BindingResult result) {
if (result.hasErrors()) {
return "appointments/new";
}
appointmentBook.addAppointment(appointment);
return "redirect:/appointments";
}
}
value的url值为以下三类:
1)可以指定为普通的具体值;
2) 可以指定为含有某变量的一类值(URI Template Patterns with Path Variables);
3) 可以指定为含正则表达式的一类值 (URI Template Patterns with Regular Expressions);
@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable String ownerId, Model model) {
Owner owner = ownerService.findOwner(ownerId);
model.addAttribute("owner", owner);
return "displayOwner";
}
@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")
public void handle(@PathVariable String version, @PathVariable String extension) {
// ...
}
}
/**除了简单地定义{username}变量,还可以定义正则表达式进行更精确的控制,定义语法是{变量名:正则表达式}[a-zA-Z0-9_]+是一个正则表达式,表示只能包含小写字母,大写字母,数字,下划线。如此设置URL变量规则后,不合法的URL则不会被处理,直接由SpringMVC框架返回404Not Found。*/
@RequestMapping("/user/{username:[a-zA-Z0-9_]+}/blog/{blogId}")
3、consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
4、produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
@Controller
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
public void addPet(@RequestBody Pet pet, Model model) {
// implementation omitted
}
@Controller
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {
// implementation omitted
}
5、params: 指定request中必须包含某些参数值时,才让该方法处理。
6、headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
// implementation omitted
}
}
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {
@RequestMapping(value = "/pets", method = RequestMethod.GET, headers="Referer=http://www.ifeng.com/")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
// implementation omitted
}
}
@PathVariable(读取路径参数)
绑定路径中的占位符参数到方法参数变量中。
1)如果路径中的变量与方法中的变量名一致,可直接使用@PathVariable;
2)如果二者不一致,则使用@PathVariable(Variable)显示指定要绑定的路径中的变量 ;
3)@PathVariable只能绑定路径中的占位符参数,且路径中必须有参数;
4)@PathVariable用法参考路径参数绑定参考。
@RequestMapping("/user/{username}/blog/{blogId}")
@ResponseBody
public String getUerBlog(@PathVariable String username , @PathVariable int blogId) {
return "user: " + username + "blog->" + blogId;
}
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id2) {
System.out.println("testPathVariable: " + id2);
return SUCCESS;
}
//路径中的 id 与 方法中的 id2 绑定
//可以指定为含正则表达式的一类值( URI Template Patterns with Regular Expressions);
@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")
public void handle(@PathVariable String version, @PathVariable String extension) {
// ...
}
@RequestParam
1) 常用来处理简单类型的绑定,通过Request.getParameter() 获取的String可直接转换为简单类型的情况( String–> 简单类型的转换操作由ConversionService配置的转换器来完成);因为使用request.getParameter()方式获取参数,所以可以处理get 方式中queryString的值,也可以处理post方式中 body data的值;
2)用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,提交方式GET、POST;
3) 该注解有两个属性: value、required; value用来指定要传入值的id名称,required用来指示参数是否必须绑定;
该注解相关属性如下:
value:参数key,可以不写,默认为"";
name:和value作用一样;
required:默认值为true,可以不写;
@Controller
@RequestMapping("/pets")
@SessionAttributes("pet")
public class EditPetForm {
// ...
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@RequestParam("petId") int petId, ModelMap model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
}
// ...
该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;它是通过使用HandlerAdapter 配置的HttpMessageConverters来解析post data body,然后绑定到相应的bean上的。
因为配置有FormHttpMessageConverter,所以也可以用来处理 application/x-www-form-urlencoded的内容,处理完的结果放在一个MultiValueMap<String, String>里,这种情况在某些特殊需求下使用,详情查看FormHttpMessageConverter api;
@RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
writer.write(body);
}
@PathVariable与@RequestParam的区别
- 相同点
1)作用位置相同:都是直接修饰方法参数变量;
2)功能相似:都是将URL中的变量值映射到方法参数上;
3)都具有value属性:将URL变量名与方法参数名映射起来; - 不同点
1)对应的URL不同
@PathVariable对应的URL是REST风格,具有占位符{XXX},即URL模板;如/{id}/{name}
@RequestParam对应的URL是传统URL,key=value形式,如?id=1&name=zhaohong
2)设置默认值
@RequestParam可以通过defaultValue属性设置默认值,而@PathVariable不可以;
3)是否必需
@RequestParam可以通过required属性设置是否必需,默认为true;而@PathVariable一定是必需的。
@RequestHeader(提取header信息)
把Request请求header部分的值绑定到方法的参数上。
@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding, @RequestHeader("Keep-Alive") long keepAlive) {
//...
}
@CookieValue(提取cookie信息)
把Request header中关于cookie的值绑定到方法的参数上。
@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie) {
//...
}
@Autowired(自动导入,byType),@Qualifier(制定对象)
使用byType方式匹配。byType方式是根据属性类型在容器中寻找bean类。
@Autowired
NewsService newsService;
注意:
1.Spring先去容器中寻找NewsSevice类型的bean(先不扫描newsService字段);
2.若找不到一个bean,会抛出异常;
3.若找到一个NewsSevice类型的bean,自动匹配,并把bean装配到newsService中;
4.若NewsService类型的bean有多个,则扫描后面newsService字段进行名字匹配,匹配成功后将bean装配到newsService中。
例如:
若有多个UserRepository 类型的bean,可以用@Qualifier指定bean的名称,名称为userJdbcImps,装配到userRepository中:
@Autowired
@Qualifier("userJdbcImps")
private UserRepository userRepository;
@Resource(资源注入,byName)
默认按 byName 自动注入
@Resource有两个中重要的属性:name和type ,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用 byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource装配顺序
(1). 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常;
(2). 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常;
(3). 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常;
(4). 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入。
@Resource(name="testBean")
public TestBean testBean;
@Bean(Bean类)
相当于Spring配置文件中的标签可以在Spring容器中注入一个bean。
1、@Bean注解在返回实例的方法上,如果未通过@Bean指定bean的名称,则默认与方法名相同;
2、@Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为多例。
比如,实例化一个TestBean并交给Spring容器管理:
@Configuration
public class TestConfiguration {
@Bean
public TestBean testBean() {
return new TestBean();
}
}
@Service
public class BeanTest {
/*
默认在不指定的时候这个bean的名字就是 getBean
如果需要指定一下名字就可以
@Bean("beanlalal")
*/
@Bean
public BeanTest getBean(){
BeanTest bean = new BeanTest();
System.out.println("调用方法:"+bean);
return bean;
}
}
public class Main {
@SuppressWarnings("unused")
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
Object bean1 = context.getBean("getBean");
System.out.println(bean1);
Object bean2 = context.getBean("getBean");
System.out.println(bean2);
}
}
@Value(注入值)
将配置文件中的属性注入到容器内组件中。
当yml中的name没有对应值时,即yml中为:
name:
此时字符串name的值为"":
@Value("${name}")
public String name;
可设置注入属性的默认值(当配置文件中没有此key时,此默认值生效),语法:
@Value("${name:zch}")
public String name;// 此时,若配置文件中没有name这个key,变量name的值为zch
yml中存在key:
id: 1,2,3
@Value("${id}")
public int[] idArray;
@Value("#{'${id}'.split(',')}")
public List<String> idList;
yml中存在key:
user: “{name: ‘zs’,age: ‘23’}” #注意此值用双引号包裹
@Value("#{${user}}")
public Map<String,String> userInfo;