Spring Framework模式注解

模式注解是一种用于声明在应用中扮演“组件”角色的注解。如 Spring Framework 中的 @Repository 标注在任何类上 ,用

于扮演仓储角色的模式注解。

模式注解(角色注解)

Spring Framework 注解 场景说明
@Component 通用组件模式注解
@Controller Web 控制器模式注解
@Service 服务模式注解
@Repository 数据仓储模式注解
@Configuration 配置类模式注解

在Spring中进行装配context:component-scan 方式

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-
  7. context.xsd">
  8. <!-- 激活注解驱动特性 -->
  9. <context:annotation-config />
  10. <!-- 找寻被 @Component 或者其派生 Annotation 标记的类(Class),将它们注册为 Spring Bean -->
  11. <context:component-scan base-package="com.imooc.dive.in.spring.boot" />
  12. </beans>

在Spring中基于Java注解配置方式

  1. @ComponentScan(basePackages = "com.imooc.dive.in.spring.boot")
  2. public class SpringConfiguration {
  3. ...
  4. }

实战:自定义模式注解

@Component 模式注解具有“派生性”和“层次性”,我们能够自定义创建Bean注解

第一步:自定义SpringBean注解

  1. @Target({ElementType.TYPE})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Component
  5. public @interface MyServiceAnnotation {
  6. String value() default "";
  7. }

第二步:将注解作用在自定义Bean上

  1. @MyServiceAnnotation(value = "testBean")
  2. public class TestBean {
  3. }

第三步:测试是否可以从Spring容器中获取到自定义Bean

  1. @SpringBootApplication
  2. public class Main {
  3. public static void main(String[] args) {
  4. ConfigurableApplicationContext run = SpringApplication.run(Main.class, args);
  5. TestBean testBean = run.getBean("testBean", TestBean.class);
  6. System.out.println("testBean" + testBean.toString());
  7. run.close();
  8. }
  9. }

Spring Framework@Enable模块装配

Spring Framework 3.1 开始支持”@Enable 模块驱动“。所谓“模块”是指具备相同领域的功能组件集合, 组合所形成一个独立的单元。比如 Web MVC 模块、AspectJ代理模块、Caching(缓存)模块、JMX(Java 管 理扩展)模块、Async(异步处理)模块等。

@Enable 注解模块举例

框架实现 @Enable 注解模块 激活模块
Spring Framework @EnableWebMvc Web MVC 模块
Spring Framework @EnableTransactionManagement 事务管理模块
Spring Framework @EnableCaching Caching 模块
Spring Framework @EnableMBeanExport JMX 模块
Spring Framework @EnableAsync 异步处理模块
Spring Framework @EnableWebFlux Web Flux 模块
Spring Framework @EnableAspectJAutoProxy AspectJ 代理模块
Spring Boot @EnableAutoConfiguration 自动装配模块
Spring Boot @EnableManagementContext Actuator 管理模块
Spring Boot @EnableConfigurationProperties 配置属性绑定模块
Spring Boot @EnableOAuth2Sso OAuth2 单点登录模块
......

@Enable实现方式

  • 注解驱动方式
  • 接口编程方式

实战:自定义@Enable注解驱动实现方式

第一步:实现自定义注解@EnableMyBean

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Import(MyBeanConfig.class)
  5. public @interface EnableMyBean {
  6. }

PS:注意@Import(MyBeanConfig.class),将导入MyBeanConfig配置类的相关Bean

第二步:创建MyBeanConfig配置类

  1. @Configuration
  2. public class MyBeanConfig {
  3. @Bean(name = "hello")
  4. public String hello() {
  5. return "word";
  6. }
  7. }

第三步:在应用中测试使用@EnableMyBean

  1. @SpringBootApplication(scanBasePackages = "com.jimisun.learnspringboot.three")
  2. @EnableMyBean
  3. public class Main {
  4. public static void main(String[] args) {
  5. ConfigurableApplicationContext context =
  6. new SpringApplicationBuilder(Main.class)
  7. .web(WebApplicationType.NONE)
  8. .run(args);
  9. String bean = context.getBean("hello", String.class);
  10. context.close();
  11. }
  12. }

实战:自定义@Enable接口实现方式

第一步:实现自定义注解@EnableMyBean

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Import(MyBeanConfigSelector.class)
  5. public @interface EnableMyBean {
  6. }

PS:注意@Import(MyBeanConfigSelector.class)导入的类和@Enable注解驱动导入的不一样,这里导入的是一个实现了ImportSelector接口的类

  1. public class MyBeanConfigSelector implements ImportSelector {
  2. @Override
  3. public String[] selectImports(AnnotationMetadata annotationMetadata) {
  4. return new String[]{new MyBeanConfig().getClass().getName()};
  5. }
  6. }

PS:在MyBeanConfigSelector类中我们可以自定义复杂的逻辑,这里我们仅仅简单返回MyBeanConfig配置类。

第三步:创建MyBeanConfig配置类

  1. @Configuration
  2. public class MyBeanConfig {
  3. @Bean
  4. public String hello() {
  5. return "word";
  6. }
  7. }

第四步:在应用中测试使用@EnableMyBean

  1. @SpringBootApplication(scanBasePackages = "com.jimisun.learnspringboot.four")
  2. @EnableMyBean
  3. public class Main {
  4. public static void main(String[] args) {
  5. ConfigurableApplicationContext context =
  6. new SpringApplicationBuilder(Main.class)
  7. .web(WebApplicationType.NONE)
  8. .run(args);
  9. String bean = context.getBean("hello", String.class);
  10. context.close();
  11. }
  12. }

PS:其实@Enable接口的实现方式和@Enable注解实现方式是基本一样的,只不过多了一个步骤,方便我们更灵活地进行编写逻辑。

Spring Framework条件装配

从 Spring Framework 3.1 开始,允许在 Bean 装配时增加前置条件判断

Spring 注解 场景说明 起始版本
@Profile 配置化条件装配 3.1
@Conditional 编程条件装配 4.0

实战:自定义@Profile 配置化条件装配

第一步:自定义创建某服务不同的@Profile实现类

  1. public interface UserService {
  2. void println();
  3. }
  1. @Service
  2. @Profile("vip")
  3. public class VipUserservice implements UserService {
  4. @Override
  5. public void println() {
  6. System.out.println("I am VIP User");
  7. }
  8. }
  1. @Service
  2. @Profile("common")
  3. public class CommonUserservice implements UserService {
  4. @Override
  5. public void println() {
  6. System.out.println("I am Common User");
  7. }
  8. }

第二步:在构建Spring容器指定配置

  1. @ComponentScan(basePackages = "com.jimisun.learnspringboot.two")
  2. public class Main {
  3. public static void main(String[] args) {
  4. ConfigurableApplicationContext run = new SpringApplicationBuilder(Main.class).
  5. web(WebApplicationType.NONE).
  6. profiles("vip").
  7. run(args);
  8. UserService bean = run.getBean(UserService.class);
  9. bean.println();
  10. run.close();
  11. }
  12. }

实战:自定义@Conditional 编程条件装配

第一步:创建一个自定义注解

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target({ElementType.TYPE, ElementType.METHOD})
  3. @Documented
  4. @Conditional({MyOnConditionProperty.class})
  5. public @interface MyConditionOnPropertyAnnotion {
  6. String prefix() default "";
  7. }

PS:注意@Conditional注解,将会找到MyOnConditionProperty类的matches方法进行条件验证

第二步:创建该注解的条件验证类,该类实现Condition接口

  1. public class MyOnConditionProperty implements Condition {
  2. @Override
  3. public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
  4. Map<String, Object> annotationAttributes =
  5. annotatedTypeMetadata.getAnnotationAttributes(MyConditionOnPropertyAnnotion.class.getName());
  6. String prefix = String.valueOf(annotationAttributes.get("prefix"));
  7. return prefix.equals("pass");
  8. }
  9. }

第三步:在Spring应用中应用条件装配

  1. @SpringBootApplication
  2. public class Main {
  3. @Bean(name = "hello")
  4. @MyConditionOnPropertyAnnotion(prefix = "pass")
  5. public String hello() {
  6. return "word";
  7. }
  8. public static void main(String[] args) {
  9. ConfigurableApplicationContext context =
  10. new SpringApplicationBuilder(Main.class)
  11. .web(WebApplicationType.NONE)
  12. .run(args);
  13. String bean = context.getBean("hello", String.class);
  14. context.close();
  15. }
  16. }

PS:本例自定义的MyConditionOnPropertyAnnotion在应用中装配的时候可以指定prefix值,该值将会在实现了Condition借口的matches进行条件验证,如果验证通过,则在Spring容器中装配该Bean,反之则不装配。

SpringBoot 自动装配

在 Spring Boot 场景下,基于约定大于配置的原则,实现 Spring 组件自动装配的目的。其中底层使用了一系列的Spring Framework手动装配的方法来构成Spring Boot自动装配。

自定义SpringBoot自动装配

  1. 激活自动装配 - @EnableAutoConfiguration
  2. 实现自动装配 - XXXAutoConfiguration
  3. 配置自动装配实现 - META-INF/spring.factories

第一步 :激活自动装配 - @EnableAutoConfiguration

  1. @EnableAutoConfiguration
  2. public class Main {
  3. public static void main(String[] args) {
  4. ConfigurableApplicationContext context =
  5. new SpringApplicationBuilder(Main.class)
  6. .web(WebApplicationType.NONE)
  7. .run(args);
  8. String bean = context.getBean("hello", String.class);
  9. context.close();
  10. }
  11. }

第二步:实现自动装配 - XXXAutoConfiguration

  1. @Configuration
  2. @EnableMyBean
  3. public class HelloWordAutoConfiguration {
  4. }

PS:这里使用了上面我们创建的@EnableMyBean,这个注解会注入一个名为“hello"的Bean

第三步:配置自动装配实现 - META-INF/spring.factories

在ClassPath目录下创建META-INF文件夹再创建spring.factories文件

  1. #配置自己的自动装配Bean
  2. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  3. com.jimisun.learnspringboot.five.HelloWordAutoConfiguration

最后:运行测试第一步中的Main方法,看是否能获取到名为“hello”的Bean

本章总结

本章我们主要了解了Spring Framework的模式注解装配,@Enable装配和条件装配。对于SpringBoot的自动装配我们仅仅做了一下演示,遵循SpringBoot装配的三个步骤,我们就可以运行SpringBoot的自动装配。但是对于SpringBoot为什么要遵循这三个步骤?自动装配的原理?我们不知所以然,所以下一章节我们仍然以SpringBoot的自动装配为主题,对SpringBoot的底层源码做剖析。

该教程所属Java工程师之SpringBoot系列教程,本系列相关博文目录 Java工程师之SpringBoot系列教程前言&目录

一步步从Spring Framework装配掌握SpringBoot自动装配的更多相关文章

  1. Spring Boot之从Spring Framework装配掌握SpringBoot自动装配

    Spring Framework模式注解 模式注解是一种用于声明在应用中扮演“组件”角色的注解.如 Spring Framework 中的 @Repository 标注在任何类上 ,用于扮演仓储角色的 ...

  2. SpringBoot源码学习1——SpringBoot自动装配源码解析+Spring如何处理配置类的

    系列文章目录和关于我 一丶什么是SpringBoot自动装配 SpringBoot通过SPI的机制,在我们程序员引入一些starter之后,扫描外部引用 jar 包中的META-INF/spring. ...

  3. SpringBoot启动流程分析(五):SpringBoot自动装配原理实现

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  4. SpringBoot学习(三)探究Springboot自动装配

    目录 什么是自动装配 何时自动装配 原理分析 注:以下展示的代码springboot的版本为2.0.3版.因源码过长,大家选择展开代码 ㄟ( ▔, ▔ )ㄏ 什么是自动装配 自动装配还是利用了Spri ...

  5. springboot自动装配

    Spring Boot自动配置原理 springboot自动装配 springboot配置文件 Spring Boot的出现,得益于“习惯优于配置”的理念,没有繁琐的配置.难以集成的内容(大多数流行第 ...

  6. springboot自动装配(1)---@SpringBootApplication注解怎么自动装配各种组件

    1.对于springboot个人认为它就是整合了各种组件,然后提供对应的自动装配和启动器(starter) 2.@SpringBootApplication注解其实就是组合注解,通过它找到自动装配的注 ...

  7. springboot自动装配(3)---条件注解@Conditional

    之前有说到springboot自动装配的时候,都是去寻找一个XXXAutoConfiguration的配置类,然而我们的springboot的spring.factories文件中有各种组件的自动装配 ...

  8. SpringBoot自动装配原理解析

    本文包含:SpringBoot的自动配置原理及如何自定义SpringBootStar等 我们知道,在使用SpringBoot的时候,我们只需要如下方式即可直接启动一个Web程序: @SpringBoo ...

  9. springboot自动装配redis在pool下偶尔出现连接异常的问题

    jedis pool的配置其实是采用 org.apache.commons.pool2.impl.GenericObjectPoolConfig类的配置项. jedis 2.9版本代码如下: pack ...

随机推荐

  1. imx6 fec分析

    /***************************************************************************** * imx6 fec分析 * 本文主要分析 ...

  2. C# HttpClientHelper请求

    public class HttpClientHelper { /// <summary> /// get请求 /// </summary> /// <param nam ...

  3. Unity3D-光照贴图技术

    概念 Lightmapping光照贴图技术是一种增强静态场景光照效果的技术,其优点是可以通过较少的性能消耗使静态场景看上去更加真实,丰富,更加具有立体感:缺点是不能用来实时地处理动态光照.当游戏场景包 ...

  4. 使用C#压缩解压rar和zip格式文件

    为了便于文件在网络中的传输和保存,通常将文件进行压缩操作,常用的压缩格式有rar.zip和7z,本文将介绍在C#中如何对这几种类型的文件进行压缩和解压,并提供一些在C#中解压缩文件的开源库. 在C#. ...

  5. mysql命令收集

    1.显示当前用户的权限

  6. Tomcat 配置 项目 到tomcat目录外面 和 域名绑定访问(api接口、前端网站、后台管理网站)

    先停止tomcat服务 1.进入apache-tomcat-7.0.68/conf/Catalina/localhost(如果之前还都没有启动过tomcat,是不会有此目录的,先启动一次再关闭,会自动 ...

  7. hadoop2.7.1单机和伪集群的搭建-0

    内容中包含 base64string 图片造成字符过多,拒绝显示

  8. Android:控件布局(相对布局)RelativeLayout(转)

    相对布局常用属性: 子类控件相对子类控件:值是另外一个控件的id android:layout_above----------位于给定DI控件之上android:layout_below ------ ...

  9. 查看系统资源使用情况:vmstat

    vmstat命令可以动态地查看系统资源的使用情况,如内存/交换分区/CPU的使用情况,通过使用该命令可以判断系统的瓶颈在哪里: [root@localhost ~]$ vmstat 1 5 # 表示每 ...

  10. STM32的操作过程,寄存器配置与调试过程(转载)

    很多学习stm32的,为什么学习stm32他也不知道,我们所知道的就是各个论坛讨论stm32的很多,而我们很多人之所以学习stm32是很多的淘宝卖家做了大量的图片文字宣传,于是我们经不住诱惑就买了板子 ...