文章目录
一、@ComponentScan
源码:
@Retention(value=RUNTIME)
@Target(value=TYPE)
@Documented
@Repeatable(value=ComponentScans.class)
public @interface ComponentScan
- @ComponentScan注解用于配置组件扫描,在spring xml配置文件中用
<context:component-scan>
标签来表示。可以配置basePackageClasses()
或basePackages()
来定义要扫描的特定包,如果未定义,则从声明此注解的类的包中扫描(组件注解包括@Controller、@Service、@Component等)。
1. basePackages
- 用于配置扫描被注解的组件的包
- 例如:
@ComponentScan(basePackages={"com.fullexception.controller","com.fullexception.service"})
- 指定扫描com.fullexception.controller和com.fullexception.service包。
2. value
- basePackages的简写版,当只需要配置一个属性的时候可以用此属性
- 例如:
@ComponentScan(value="com.fullexception.controller")
- 或者
@ComponentScan("com.fullexception.controller")
- 扫描com.fullexception.controller包。
3. basePackageClasses
- 类型安全版的basePackages
- 例如:
@ComponentScan(basePackageClasses={UserController.class, UserService.class})
- 扫描UserController和UserService类所在的包。
4. nameGenerator
- 指定bean命名策略的方法,默认的命名策略为AnnotationBeanNameGenerator
protected String buildDefaultBeanName(BeanDefinition definition) {
String shortClassName = ClassUtils.getShortName(definition.getBeanClassName());
return Introspector.decapitalize(shortClassName);
}
-
观察上述源码,默认命名规范得到的是首字母小写的类名
-
我们可以自定义命名规范,创建AimeeAnnotationBeanNameGenerator类并继承AnnotationBeanNameGenerator,重写buildDefaultBeanName方法,得到类全名。
package com.fullexception.util;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
public class AimeeAnnotationBeanNameGenerator extends AnnotationBeanNameGenerator {
@Override
protected String buildDefaultBeanName(BeanDefinition definition) {
return definition.getBeanClassName();
}
}
@ComponentScan(nameGenerator=AimeeAnnotationBeanNameGenerator.class)
- 绕过spring自动注入bean,可以通过类全名的方式手动获得类
ApplicationContext.getBean("com.fullexception.service.serviceImpl.UserServiceImpl")
5. lazyInit
- 指定被扫描的bean是否注册为懒加载模式。
- 例如:
@ComponentScan(lazyInit=true)
6. scopeResolver
- 继承自ScopeMetadataResolver,用来解析已经检测到的组件。
7. scopedProxy
- 指示是否应该为检测到的组件生成代理,这在使用代理样式的方式时可能是必要的。
默认情况下是遵从用于执行实际扫描的组件扫描器的默认行为。
8. resourcePattern
- 控制符合组件检测的类文件。
9. useDefaultFilters
- 指示是否应该启用带有@component、@Repository、@service或@controller注解的类的自动检测。
例如:
@ComponentScan(useDefaultFilters=false)
10. includeFilters
- 指定哪些类型适合进行组件扫描。
- 将basePackages()中指定的范围再次筛选缩小至符合指定的拦截器要求的组件。
注意,如果指定的话,这些过滤器将被应用于默认过滤器。在指定的基本包下,与给定的过滤器相匹配的任何类型都将被包括在内,即使它不符合缺省过滤器(也就是说,不使用@component注解)。
11. excludeFilters
- 指定哪些类型不适合进行组件扫描。
二、@SpringBootApplication
- 源码:
@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters={@ComponentScan.Filter(type=CUSTOM,classes=TypeExcludeFilter.class),})
public @interface SpringBootApplication
- 被SpringBootApplication注解的类相当于是一个配置类,它声明一个或多个@bean方法并且触发自动配置和组件扫描功能,引用本注解相当于@Configuration、@EnableAutoConfiguration和@ComponentScan三个注解效果的叠加
1. scanBasePackages
-
用于配置组件扫描的基本包。可以用scanBasePackageClassess()这种类型安全的方式来替代scanBasePackages
-
例如:
@SpringBootApplication(scanBasePackages={"com.fullexception.controller","com.fullexception.service"})
-
或者
@SpringBootApplication(scanBasePackages="com.fullexception.controller")
-
在进行组件扫描的时候会在名称为com.fullexception.controller和com.fullexception.service的包下进行扫描。
2. scanBasePackageClasses
- scanBasePackages的类型安全替代方案。配置指定类所在的包
- 例如:
@SpringBootApplication(scanBasePackageClasses ={com.fullexception.entity.Article.class})
- 扫描Article类所在的包
3. exclude
- 按class将指定的类排除在自动配置之外(类型安全)。
- 例如:
@SpringBootApplication(exclude=Article.class)
- 在自动配置的时候不会配置Article类
4. excludeName
-
按名称将指定的类排除在自动配置之外。
-
例如:
@SpringBootApplication(excludeName="com.fullexception.entity.User")
-
或者
@SpringBootApplication(excludeName={"com.fullexception.entity.Article", "com.fullexception.entity.User"})
-
在自动配置的时候不会配置com.fullexception.entity包下的Article和User类
-
实际应用:扫描com.fullexception.entity下的所有类,但排除Article类
@SpringBootApplication(scanBasePackages={"com.fullexception.controller"), exclude=Article.class)
三、@EnableAutoConfiguration
- 源码:
@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(value=AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration
- 使Spring应用上下文有自动配置的功能,尝试猜测和配置可能需要的bean,自动配置类通常基于类路径和自定义的bean。
- 如果添加了@SpringBootApplication注解,自动配置上下文将自动激活,并且添加@EnableAutoConfiguration注解,但是不会添加@EnableAutoConfiguration注解的任何附加功能。
1. exclude
- 排除特定的类,这样它就永远不会被应用了(类型安全)。
- 例如:
@EnableAutoConfiguration(exclude={UserServiceImpl.class, UserMapper.class})
- 不会应用UserService和UserMapper类。
2. excludeName
- 功能同上,通过字符串表示的类名来完成过滤。
- 例如:
@EnableAutoConfiguration(excludeName={"UserServiceImpl"})
- 不会应用UserServiceImpl类。
四、@Component
- 源码:
@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Indexed
public @interface Component
- 表示带有@Component注解的类是一个“组件”。在扫描组件时,这些类被认为是自动检测的候选对象。
- 其他类级注解也可以被看作是标识一个组件,通常是一种特殊的组件:例如@repository注解或AspectJ的@aspect注解。
1. value
- 可以给定一个逻辑组件的建议名称,在自动检测组件的情况下,它将被转换成Spring bean。
五、@RestController
- 源码:
@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController
- 一个方便的注解,它本身带有@controller和@responsebody。
- 被注解的类作为控制器,并且返回值直接写进http响应正文中(不会跳转页面,返回值一般为json或xml等格式的数据),异步调用使用居多。
1. value
- 可以给定一个逻辑组件的建议名称,在自动检测组件的情况下,它将被转换成Spring bean。
六、@Controller
- 源码:
@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Component
public @interface Controller
-
表明被注解的类是一个控制器
-
这个注解可以理解为@Component的一个特殊版本,允许实现类在类路径扫描时被检测到,它通常和基于@RequestMapping的类(例如@GetMapping、@PostMapping、@PutMapping、@DeleteMapping等等)配合使用。
1. value
- 可以给定一个逻辑组件的建议名称,在自动检测组件的情况下,它将被转换成Spring bean。
七、@ResponseBody
- 源码:
@Target(value={TYPE,METHOD})
@Retention(value=RUNTIME)
@Documented
public @interface ResponseBody
- 此注解表示方法的返回值要绑定到web响应主体中(异步调用时经常使用,返回值多为json、xml等数据体),不会进行跳转,支持servlet环境中的注解处理程序方法, 可在方法上添加注解。
- 在4.0版本后,此注解支持添加到类型(Class)级别上,在这种情况下注解属性是继承的,不需要单独再去为方法添加注解。
八、@Autowired
- 源码:
@Target(value={CONSTRUCTOR,METHOD,PARAMETER,FIELD,ANNOTATION_TYPE})
@Retention(value=RUNTIME)
@Documented
public @interface Autowired
- @Autowired是用在JavaBean中的注解,通过类型、类名称等形式,用来给指定的字段或方法注入所需的外部资源。
- 定义一个UserService接口
public interface UserService {
String getUserName();
}
- UserService的实现类
@Service("userService")
public class UserServiceImpl implements UserService {
@Override
public User getUserName() {
return "张三";
}
}
- 接下来定义Controller
@Controller
public class UserController {
@Autowired
private UserService userService2;
}
- 这时程序运行@Autowired时是通过比对类型的方式到IoC容器中查找UserService的实现,目标是UserServiceImpl(即便UserServiceImpl里@Service(“userService”)的名称为userService,与controller中定义的userService2不同也可以成功注入),因为容器中目前只有一个实现。
- 那这时我们再定义一个实现
@Service("userService1")
public class UserServiceImpl1 implements UserService {
@Override
public User getUserName() {
return "李四";
}
}
- 再次运行时,控制台出现如下警告
Field userService2 in com.fullexception.controller.UserController required a single bean, but 2 were found:
- userService: defined in file [D:\Users\Administrator\Documents\workspace-sts-3.8.4.RELEASE\alicia_do\target\classes\com\fullexception\service\serviceImpl\UserServiceImpl.class]
- userService1: defined in file [D:\Users\Administrator\Documents\workspace-sts-3.8.4.RELEASE\alicia_do\target\classes\com\fullexception\service\serviceImpl\UserServiceImpl1.class]
-我们可以看到错误提示信息,显然系统想通过名称去对比,但是没有发现目标,因此提示类型符合的有两条,但是名称userService2和userService、userService1对应不上。由此可见,多个实现采用的是比对名称的方式。
1. required
- 当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用 @Autowired(required = false)
- 上述方法中如果UserService接口没有一个实现类,可以通过配置Controller中的@Autowired(required = false)来避免启动错误。
九、@PathVariable
- 源码:
@Target(value=PARAMETER)
@Retention(value=RUNTIME)
@Documented
public @interface PathVariable
-
注解指明参数绑定到URI模板变量,并通过@PathVariable注解取得url中的参数
-
例:
@Autowired
private UserService userService;
@GetMapping(value = "/index/{id}")
public String showIndex(@PathVariable("id") Integer id, HttpSession session) {
User user = userService.getUserById(id);
session.setAttribute("user", user);
return "index";
}
- 访问url:
http://127.0.0.1:8080/index/1
1. value/name
- 要绑定的变量的名称
- 例如:
@PathVariable(value="id")
@PathVariable(name="id")
@PathVariable("id")
感谢阅读:
- 由于个人水平有限,如果有不对的地方希望各位能够留言指正,
- 如需转载,请标明出处:https://blog.csdn.net/sanbowla/article/details/81136274,谢谢!
- 本文源码及部分说明来自spring.io