① 注解

和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作。

本质上:所有一切的操作都是Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行。

② 扫描

Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后续操作。

一、SpringIOC 常用注解

四个典型注解没有本质区别:对于Spring使用IOC容器管理这些组件来说没有区别。所以@Controller、@Service、@Repository这三个注解只是给开发人员看的,让我们能够便于分辨组件的作用。

注意:虽然它们本质上一样,但是为了代码的可读性,为了程序结构严谨我们肯定不能随便胡乱标记。

1. 使用@Component注解标记的普通组件

通过查看源码我们得知,@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。

@Component
public class CommonComponent {
}

2. 使用@Controller注解标记的控制器组件

这个组件就是我们在三层架构中表述层里面,使用的控制器。以前是Servlet,以后我们将会使用Controller来代替Servlet。

@Controller
public class SoldierController {
}

3. 使用@Service注解标记的业务逻辑组件

这个组件就是我们在三层架构中使用的业务逻辑组件。

@Service
public class SoldierService {
​
}

4. 使用@Repository注解标记的持久化层组件

这个组件就是我们以前用的Dao类,但是以后我们整合了Mybatis,这里就变成了Mapper接口,而Mapper接口是由Mybatis和Spring的整合包负责扫描的。


由于Mybatis整合包想要把Mapper接口背后的代理类加入Spring的IOC容器需要结合Mybatis对Mapper配置文件的解析,所以这个事情是Mybatis和Spring的整合包来完成,将来由Mybatis负责扫描,也不使用@Repository注解。

@Repository
public class SoldierDao {
}

5. 组件的beanName

在我们使用XML方式管理bean的时候,每个bean都有一个唯一标识,便于在其他地方引用。现在使用注解后,每个组件仍然应该有一个唯一标识。

① 默认情况

类名首字母小写就是bean的id。例如:SoldierController类对应的bean的id就是soldierController。

@Controller
public class SoldierController {
}

② 使用value属性指定

@Controller(value = "tianDog")
public class SoldierController {
}

当注解中只设置一个属性时,value属性的属性名可以省略:

@Service("smallDog")
public class SoldierService {
​
}

二、SpringIOC 注入bean的注解

1. 自动装配的实现前提

参与自动装配的组件(需要装配别人、被别人装配)全部都必须在IOC容器中。

2. @Autowired注解

在成员变量上直接标记@Autowired注解即可,不需要提供setXxx()方法。

以后我们在项目中的常用的正式用法就是以下这样:

@Controller
public class SoldierController {@Autowiredprivate SoldierService soldierService;public void getMessage() {soldierService.getMessage();}}

3. @Autowired注解其他细节

① 标记在构造器

@Controller(value = "tianDog")
public class SoldierController {private SoldierService soldierService;@Autowiredpublic SoldierController(SoldierService soldierService) {this.soldierService = soldierService;}……

② 标记在setXxx()方法

@Controller("tianDog")
public class SoldierController {
​private SoldierService soldierService;
​@Autowiredpublic void setSoldierService(SoldierService soldierService) {this.soldierService = soldierService;}……

4. @Autowired工作流程 

  • 首先根据所需要的组件类型到IOC容器中查找

    • 能够找到唯一的bean:直接执行装配

    • 如果完全找不到匹配这个类型的bean:装配失败

    • 和所需类型匹配的bean不止一个

      • 没有@Qualifier注解:根据@Autowired标记位置成员变量的变量名作为bean的id进行匹配

        • 能够找到:执行装配
        • 找不到:装配失败
      • 使用@Qualifier注解:根据@Qualifier注解中指定的名称作为bean的id进行匹配

        • 能够找到:执行装配
        • 找不到:装配失败

@Qualifier注解:根据@Qualifier注解中指定的名称作为bean的id进行匹配

@Controller(value = "tianDog")
public class SoldierController {@Autowired@Qualifier(value = "maomiService222")// 根据面向接口编程思想,使用接口类型引入Service组件private ISoldierService soldierService;

5. @Autowired注解佛系装配

给@Autowired注解设置required = false属性表示:能装就装,装不上就不装。但是实际开发时,基本上所有需要装配组件的地方都是必须装配的,用不上这个属性。

@Controller(value = "tianDog")
public class SoldierController {
​// 给@Autowired注解设置required = false属性表示:能装就装,装不上就不装@Autowired(required = false)private ISoldierService soldierService;

6. @Configuration注解 创建配置类 

使用@Configuration注解将一个普通的类标记为Spring的配置类。

@Configuration
public class MyConfiguration {
}

7. @Bean注解 

@Bean注解相当于XML配置文件中的bean标签
@Bean注解标记的方法的返回值会被放入IOC容器

@Configuration
public class MyConfiguration {// @Bean注解相当于XML配置文件中的bean标签// @Bean注解标记的方法的返回值会被放入IOC容器@Beanpublic CommonComponent getComponent() {CommonComponent commonComponent = new CommonComponent();commonComponent.setComponentName("created by annotation config");return commonComponent;}
}

8. @ComponentScan注解

@ComponentScan注解 在配置类中配置自动扫描的包

@Configuration
@ComponentScan("com.liush.ioc.component")
public class MyConfiguration {……

9. Junit4和Junit5注解 

Junit4注解

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {"classpath:applicationContext.xml"})
public class AOPTest {}

Junit5注解

@ExtendWith(SpringExtension.class) 表示使用 Spring 提供的扩展功能。
@ContextConfiguration(value = {"classpath:spring-context.xml"}) 还是用来指定 Spring 配置文件位置,和整合 junit4 一样。

@SpringJUnitConfig 注解综合了前面两个注解的功能,此时指定 Spring 配置文件位置即可。但是注意此时需要使用 locations 属性,不是 value 属性了。

@SpringJUnitConfig(locations = {"classpath:spring-context.xml"})
public class Junit5IntegrationTest {}
JUnit4 JUnit5 说明
@Test @Test 表示该方法是一个测试方法。JUnit5与JUnit 4的@Test注解不同的是,它没有声明任何属性,因为JUnit Jupiter中的测试扩展是基于它们自己的专用注解来完成的。这样的方法会被继承,除非它们被覆盖
@BeforeClass @BeforeAll 表示使用了该注解的方法应该在当前类中所有使用了@Test @RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之前 执行;
@AfterClass @AfterAll 表示使用了该注解的方法应该在当前类中所有使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之后执行;
@Before @BeforeEach 表示使用了该注解的方法应该在当前类中每一个使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之前 执行
@After @AfterEach 表示使用了该注解的方法应该在当前类中每一个使用了@Test、@RepeatedTest、@ParameterizedTest或者@TestFactory注解的方法之后 执行
@Ignore @Disabled 用于禁用一个测试类或测试方法
@Category @Tag 用于声明过滤测试的tags,该注解可以用在方法或类上;类似于TesgNG的测试组或JUnit 4的分类。
@Parameters @ParameterizedTest 表示该方法是一个参数化测试
@RunWith @ExtendWith @Runwith就是放在测试类名之前,用来确定这个类怎么运行的
@Rule @ExtendWith Rule是一组实现了TestRule接口的共享类,提供了验证、监视TestCase和外部资源管理等能力
@ClassRule @ExtendWith @ClassRule用于测试类中的静态变量,必须是TestRule接口的实例,且访问修饰符必须为public。

三、SpringAOP 常用注解

1. @Aspect注解:表示这个类是一个切面类

@Order(2)注解:表示切面的优先级

  • @Order(较小的数):优先级高
  • @Order(较大的数):优先级低
@Component
@Aspect //表明当前是一个切面类
public class WuDaAspect {//1.获取连接点的信息@Before("execution(* *Bing(..))")public void song(JoinPoint joinPoint){//joinPoint称之为连接点//1.获取方法签名Signature signature = joinPoint.getSignature();System.out.println(signature.getName());System.out.println(signature.getModifiers());System.out.println(signature.getDeclaringType().getName());//2.获取目标方法的实际参数Arrays.asList(joinPoint.getArgs()).forEach(System.out::println);}//2.获取目标方法的返回值信息@AfterReturning(value = "execution(* *Bing(..))",returning = "number")public void song2(Integer number){System.out.println("目标方法的返回值是:"+number);}//3.获取目标方法的异常信息@AfterThrowing(value = "execution(* *Bing(..))",throwing = "throwable")public void song3(Throwable throwable){System.out.println("得到的异常信息:"+throwable.getMessage());System.out.println("没事没事,高蛋白!");}}

2. @Before注解:在方法执行之前执行(方法上)

value属性:切入点表达式,告诉Spring当前通知方法要套用到哪个目标方法上

@Before("execution(* *Bing(..))")

3. @After注解: 在方法执行之后执行(方法上) 

从spring5.3.x开始,增强执行顺序是:
@Before
@AfterReturning 或者 @AfterThrowing
@After

@Component
@Aspect
public class WuDaAspect {@Before("execution(* *Bing(..))")public void song(){System.out.println("1.送大麦茶...");}@AfterReturning("execution(* *Bing(..))")public void song2(){System.out.println("2.送玫瑰茶");}@AfterThrowing("execution(* *Bing(..))")public void song3(){System.out.println("3.送茉莉花茶");}@After("execution(* *Bing(..))")public void song4(){System.out.println("4.送菊花茶...");}
}

4. @AfterReturning注解标记返回通知方法

在返回通知中,通过@AfterReturning注解的returning属性获取目标方法的返回值


在返回通知中获取目标方法返回值分两步:
第一步:在@AfterReturning注解中通过returning属性设置一个名称
第二步:使用returning属性设置的名称在通知方法中声明一个对应的形参

// @AfterReturning注解标记返回通知方法
// 在返回通知中获取目标方法返回值分两步:
// 第一步:在@AfterReturning注解中通过returning属性设置一个名称
// 第二步:使用returning属性设置的名称在通知方法中声明一个对应的形参
@AfterReturning(value = "execution(public int com.liush.aop.api.Calculator.add(int,int))",returning = "targetMethodReturnValue"
)
public void printLogAfterCoreSuccess(JoinPoint joinPoint, Object targetMethodReturnValue) {String methodName = joinPoint.getSignature().getName();System.out.println("[AOP返回通知] "+methodName+"方法成功结束了,返回值是:" + targetMethodReturnValue);
}

5. @AfterThrowing注解标记异常通知方法

在异常通知中,通过@AfterThrowing注解的throwing属性获取目标方法抛出的异常对象


在异常通知中获取目标方法抛出的异常分两步:
第一步:在@AfterThrowing注解中声明一个throwing属性设定形参名称
第二步:使用throwing属性指定的名称在通知方法声明形参,Spring会将目标方法抛出的异常对象从这里传给我们

// @AfterThrowing注解标记异常通知方法
// 在异常通知中获取目标方法抛出的异常分两步:
// 第一步:在@AfterThrowing注解中声明一个throwing属性设定形参名称
// 第二步:使用throwing属性指定的名称在通知方法声明形参,Spring会将目标方法抛出的异常对象从这里传给我们
@AfterThrowing(value = "execution(public int com.liush.aop.api.Calculator.add(int,int))",throwing = "targetMethodException"
)
public void printLogAfterCoreException(JoinPoint joinPoint, Throwable targetMethodException) {String methodName = joinPoint.getSignature().getName();System.out.println("[AOP异常通知] "+methodName+"方法抛异常了,异常类型是:" + targetMethodException.getClass().getName());
}

6. @Around注解:标明环绕通知方法

环绕通知对应整个try...catch...finally结构,包括前面四种通知的所有功能。

@Around(value = "com.liush.spring.aop.aspect.LogAspect.declarPointCut()")
public Object roundAdvice(ProceedingJoinPoint joinPoint) {

7. @PointCut注解:切入点表达式重用

在一处声明切入点表达式之后,其他有需要的地方引用这个切入点表达式。易于维护,一处修改,处处生效。声明方式如下:

// 切入点表达式重用
@Pointcut("execution(* *..*.add(..))")
public void declarPointCut() {}

切点表达式的语法:
① 用*号代替“权限修饰符”和“返回值”部分表示“权限修饰符”和“返回值”不限
   * *Bing(..)   第一个*表示访问修饰符和返回值类型不限
   public void *Bing(..) 访问修饰符必须是public,返回值类型必须是void
   * void *Bing(..)  错误写法 , 比较特殊的是,这种写法是允许的: public * *Bing(..)
② 在包名部分,*代表某一层包任意。
   例如: com.liush.dao.*.*.*Bing(..)  com.atguigu.dao包下的任意子包(有且只有一层),第二个*代表任意类名
③ 在包名部分,*..代表任意层的包
   例如: com.liush.*..*.*Bing(..) com.atguigu下任意子包(层数也是任意的)
④ 在类名部分,*代表任意类名称,也可以代表部分类名称
   例如:com.liush.dao.User*.*(..)
        com.liush.dao.*.add(..)
⑤ 在方法名部分:*代表方法名任意,也可以代表方法名的部分任意
   例如:com.liush.service.impl.UserServiceImpl.get*(..)   表示UserServiceImpl下的get方法
⑥ 在方法的参数部分:
   (..) 参数个数和类型任意
   (int,..) 第一个参数必须是int,后面的参数任意
   (int,..) 和(Integer,..)不是一回事
⑦ 在方法的访问修饰符和返回值部分:
   public int *..*.*(..)  所有的public修饰的方法,而且要求返回值类型是int
   * int *..*.*(..)    错误写法,因为第一个*已经表明访问修饰符和返回值类型不限制
   特殊的,这个是正确的:  public * *..*.*(..)
⑧ 切点表达式中也是支持逻辑运算符的: && || !
execution(* com.liush.book.service.impl.User*.*(..)) || execution(* com.liush.book.service.impl.Book*.*(..))

8. 事务的注解 

① 事务基本注解:只读、回滚、超时

@Transactional

@Transactional(readOnly = true)

  • readOnly = true:把当前事务设置为只读

@Transactional(readOnly = false, timeout = 3)

  • readOnly = false:把当前事务设置为非只读
  • timeout = 3:过三秒超时自动结束事务

@Transactional(rollbackFor = Exception.class)

  • rollbackFor属性:需要设置一个Class类型的对象
  • rollbackForClassName属性:需要设置一个字符串类型的全类名
  • rollbackFor = Exception.class,noRollbackFor = FileNotFoundException.class:除了 FileNotFoundException 之外,其他所有 Exception 范围的异常都回滚;但是碰到 FileNotFoundException 不回滚。

② 事务隔离级别

  • isolation属性:设置事务的隔离级别

@Transactional(isolation = Isolation.READ_UNCOMMITTED)

  • READ_UNCOMMITTED:读未提交

@Transactional(isolation = Isolation.READ_COMMITTED)

  • READ_COMMITTED:读已提交

@Transactional(isolation = Isolation.Repeatable_Read)

  • Repeatable_Read:可重复读

@Transactional(isolation = Isolation.SERIALIZABLE)

  • SERIALIZABLE:序列化

③ 事务传播行为

  • propagation属性:设置事务的传播行为

@Transactional(propagation = Propagation.REQUIRED)

@Transactional(propagation = Propagation.SUPPORTS)

@Transactional(propagation = Propagation.MANDATORY)

@Transactional(propagation = Propagation.REQUIRES_NEW)

@Transactional(propagation = Propagation.NOT_SUPPORTED)

@Transactional(propagation = Propagation.NEVER)

@Transactional(propagation = Propagation.NESTED)

四、SpringMVC 常用注解

1. @RequestMapping

@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

@RequestMapping注解的作用就是将请求 和 处理请求的 控制器方法 关联起来,建立映射关系。
SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。

2. @RequestMapping

@RequestMapping(value = "/emp",method = RequestMethod.GET)
@GetMapping("/emp")
@RequestMapping(value = "/emp",method = RequestMethod.POST)
@POSTMapping("/emp")

@RequestMapping注解的作用就是将请求 和 处理请求的 控制器方法 关联起来,建立映射关系。
SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。

属性:

  • value:指定为形参赋值的请求参数的参数名。
  • required:设置是否必须传输此请求参数,默认值为true,如果为true没传值则400。
  • defaultValue:不管required属性值为true或false,当value所指定的请求参数没有传输或传输的值为""时,则使用默认值为形参赋值。

3. @RequestHander

@RequestHeader是将请求头信息和控制器方法的形参创建映射关系。

通过这个注解获取请求消息头中的具体数据。

@RequestMapping("/request/header")
public String getRequestHeader(// 使用 @RequestHeader 注解获取请求消息头信息// name 或 value 属性:指定请求消息头名称// defaultValue 属性:设置默认值@RequestHeader(name = "Accept", defaultValue = "missing") String accept
) {logger.debug("accept = " +accept);return "target";
}

4. @CookieValue

获取当前请求中的 Cookie 数据。

@RequestMapping("/request/cookie")
public String getCookie(// 使用 @CookieValue 注解获取指定名称的 Cookie 数据// name 或 value 属性:指定Cookie 名称// defaultValue 属性:设置默认值@CookieValue(value = "JSESSIONID", defaultValue = "missing") String cookieValue,// 形参位置声明 HttpSession 类型的参数即可获取 HttpSession 对象HttpSession session
) {logger.debug("cookieValue = " + cookieValue);return "target";
}

5. @RequestBody

@RequestBody可以获取请求体,需要在控制器方法设置一个形参,使用@RequestBody进行标识,当前请求的请求体就会为当前注解所标识的形参赋值。

6. @ResponseBody

@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器。

7. @RestController

@RestController注解是springMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了@Controller注解,并且为其中的每个方法添加了@ResponseBody注解。

8. @ControllerAdvice

标记为异常处理类(Java代码异常,非Http请求状态异常),一个异常处理类有很多异常处理器。

9. @ExceptionHandler

异常处理器,在异常处理类中声明。

10. @Configuration

声明此类为注解类,可代替xml配置。

11. @PathVariable 

如果我们想要获取链接地址中的某个部分的值,就可以使用 @PathVariable 注解。

主要体现在restful风格上了。

12. @RequestParam

主要用于将请求参数区域的数据映射到控制层方法的参数上

Spring 常用注解(IOC/AOP/MVC)相关推荐

  1. Spring常用注解,注解 IOC ,AOP,MVC 的理解

    文章目录 大佬总结 0.Spring常用注解 0.1.SpringBootController里面的用法 0.1.1.SpringBoot 中常用注解@Controller/@RestControll ...

  2. Spring常用注解 - 使用注解来构造IoC容器

    Spring常用注解 使用注解来构造IoC容器 用注解来向Spring容器注册Bean.需要在applicationContext.xml中注册<context:component-scan b ...

  3. Spring系列之Spring常用注解总结

    参看博客:https://www.cnblogs.com/xiaoxi/p/5935009.html 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺 ...

  4. Spring常用注解总结

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文 ...

  5. spring autowired idea都匹配上了_你清楚这几个Spring常用注解吗?

    作者:平凡希http://cnblogs.com/xiaoxi/p/5935009.html 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 如 ...

  6. Java 必须掌握的 12 种 Spring 常用注解

    转载自  Java 必须掌握的 12 种 Spring 常用注解 1.声明bean的注解 @Component 组件,没有明确的角色 @Service 在业务逻辑层使用(service层) @Repo ...

  7. autowired注解_Spring系列之Spring常用注解总结

    作者:平凡希来源:https://www.cnblogs.com/xiaoxi/p/5935009.html 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做 ...

  8. sessionattribute 被spring 扫描不到_Spring 系列之 Spring 常用注解总结(肝硬化的干货)...

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1. 如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml ...

  9. Spring系列之Spring常用注解总结 原文:https://www.cnblogs.com/xiaoxi/p/5935009.html

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文 ...

最新文章

  1. Kali Linux攻防系统(三:在Kali Linux系统中配置安全测试浏览器及系统清理备份)
  2. iphone怎么重启_苹果手机进入itunes怎么退出
  3. java命令执行类,这里设置了classpath,系统变量里的classpath将失效
  4. hadoop 2.x HA(QJM)安装部署规划
  5. 计算机键盘为啥要这样分布,你知道电脑键盘为什么这么排列吗?
  6. Ppt2010中HTML是什么,2010dw1html简介.ppt
  7. java五子棋棋盘_java五子棋项目(一)
  8. C# 程序实现功能目录
  9. Oracle SQL 优化原则(实用篇)
  10. ACL 2021 | 丁香园知识增强预训练模型
  11. 论文赏析[NAACL19]无监督循环神经网络文法 (URNNG)
  12. 我们公司不会用分布式事务!
  13. 有关注册表技术的各大网站列表
  14. JavaScript之document对象最常用相关知识总结
  15. 向量叉积分配律简单证明
  16. BN层的running_mean更新机制
  17. 基于STM32的光照度自动调节系统
  18. ChatGPT登上Time封面!这场竞赛,OpenAI赌赢了
  19. 新能源汽车车架号VIN码查询车辆信息
  20. 网络视频监控P2P解决方案

热门文章

  1. 2022年Android面试题汇集(中高级)
  2. 最新大厂Android面试题集——答案+解析
  3. Unity3d 技巧(10) -游戏上线 三星应用商店上传指南
  4. vim插件管理器之Vundle的使用
  5. 天池冠军比赛心得体会
  6. java造轮子:快速搭建一个网关服务,动态路由、鉴权看完就会(含流程图)
  7. 微信红包封面怎么制作?微信红包封面序列号如何领取
  8. 网络安全从入门到精通:30天速成教程到底有多狠?你能坚持下来么?
  9. 怎么打开iPhone的开发者模式
  10. 查准率-查全率precision recall(PR)曲线Matlab实现