Springboot自动装配原理_自动装配原理

Springboot自动装配原理_自动装配原理springboot自动装配原理详解1)传统ssm整合redis的时候需要在xml的配置文件中进行大量的配置Bean我们在这里使用springboot来代替ssm的整合,只是通过xml的形式来整合redis第一步:加入配置<dependency><groupId>org.springframework.data</grou…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

springboot自动装配原理详解

1)传统ssm整合redis的时候 需要在xml的配置文件中 进行大量的配置Bean

我们在这里使用springboot来代替ssm的整合,只是通过xml的形式来整合redis

第一步:加入配置

<dependency>

          <groupId>org.springframework.data</groupId>

          <artifactId>spring-data-redis</artifactId>

          <version>2.0.9.RELEASE</version>

</dependency>

<dependency>

          <groupId>redis.clients</groupId>

         <artifactId>jedis</artifactId>

          <version>2.9.0</version>

</dependency>

第二步: 配置xml的bean的配置 

//配置连接池  

   <bean id=”poolConfig” class=”redis.clients.jedis.JedisPoolConfig”>   

      <property name=”minIdle” value=”10″></property>    

     <property name=”maxTotal” value=”20″></property>    

 </bean>        

  //配置连接工厂     <bean id=”jedisConnectionFactory” class=”org.springframework.data.redis.connection.jedis.JedisConnectionFactory”>         <property name=”hostName” value=”47.104.128.12″></property>         <property name=”password” value=”123456″></property>  

        <property name=”database” value=”0″></property>    

       <property name=”poolConfig” ref=”poolConfig”></property>    

 </bean>  

   //配置 redisTemplate 模版类    

 <bean id=”redisTemplate” class=”org.springframework.data.redis.core.RedisTemplate”>         <property name=”connectionFactory”  ref=”jedisConnectionFactory”/>    

     <!–如果不配置Serializer,那么存储的时候默认使用String,如果用User类型存储,那么会提示错误User can’t cast to String!  –>   

      <property name=”keySerializer”>             <bean class=”org.springframework.data.redis.serializer.StringRedisSerializer”/>   

      </property>         

    <property name=”valueSerializer”>             <bean class=”org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer”/>     

    </property>    

     <property name=”hashKeySerializer”>             <bean class=”org.springframework.data.redis.serializer.StringRedisSerializer”/>       

  </property>    

     <property name=”hashValueSerializer”>          <bean class=”org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer”/>     

    </property>

    </bean>

第三步:导入配置 

@ImportResource(locations = “classpath:beans.xml”)  此注解用于导入xml的配置文件

@SpringBootApplication

@ImportResource(locations = “classpath:beans.xml”)

@RestController public class TulingOpenAutoconfigPrincipleApplication {

          @Autowired

          private RedisTemplate redisTemplate;

          public static void main(String[] args) {

                 SpringApplication.run(TulingOpenAutoconfigPrincipleApplication.class, args);

          }

          @RequestMapping(“/testRedis”)

          public String testRedis() {

                 redisTemplate.opsForValue().set(“smlz”,”smlz”); return “OK”;

          }

 }

2)综上所述 我们发现,若整合redis的时候通过传统的整合,进行了大量的配置,那么我们来看下通过springboot自动装配整合的对比

导入依赖: 

<dependency>

          <groupId>org.springframework.boot</groupId>

          <artifactId>spring-boot-starter-data-redis</artifactId>

</dependency>

修改yml配置文件 

spring.redis.host=47.104.128.12

spring.redis.port=6379

spring.redis.password=123456

直接使用(下述代码可以不要配置,为了解决保存使用jdk的序列方式才配置的) 

@Bean

          public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)  {                                 RedisTemplate<Object, Object> template = new RedisTemplate<>();                                                                                     template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));                                                     template.setConnectionFactory(redisConnectionFactory); return template;

}​

3)传统整合和springboot自动装配 优劣势分析 

Springboot自动装配原理_自动装配原理

4)自动装配原理前的不得不说的几个注解

4.1)通过@Import注解来导入ImportSelector组件

①:写一个配置类在配置类上标注一个@Import的注解

@Configuration

@Import(value = {TulingSelector.class})

public class TulingConfig {

}​

②:在@Import注解的value值  写自己需要导入的组件 

       在selectImports方法中 就是你需要导入组件的全类名

public class TulingSelector implements ImportSelector {   

  @Override     

  public String[] selectImports(AnnotationMetadata annotationMetadata) {    

     return new String[]{“com.tuling.service.TulingServiceImpl“};  

   }

}

 核心代码:

@RestController

public class TulingController {     

    //自动注入 tulingServiceImpl   

  @Autowired   

  private TulingServiceImpl tulingServiceImpl;   

  @RequestMapping(“testTuling”)    

 public String testTuling() {   

      tulingServiceImpl.testService();       

      return “tulingOk”;   

  }

}

这里是没有标注其他注解提供给spring包扫描的

public class TulingServiceImpl {    

 public void testService() {   

      System.out.println(“我是通过importSelector导入进来的service”);     

   }

}

Springboot自动装配原理_自动装配原理 1.2)通过@Import导入ImportBeanDefinitionRegistrar 从而进来导入组件

Springboot自动装配原理_自动装配原理

 核心代码:

public class TulingImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {   

  @Override     public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, 

                                                                               BeanDefinitionRegistry beanDefinitionRegistry) {     

    //定义一个BeanDefinition

        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TulingDao.class);      

   //把自定义的bean定义导入到容器中    

     beanDefinitionRegistry.registerBeanDefinition(“tulingDao”,rootBeanDefinition);    

    }

}​

通过ImportSelector功能导入进来的

public class TulingServiceImpl {    

 @Autowired   

  private TulingDao tulingDao;     

public void testService() {      

   tulingDao.testTulingDao();         

System.out.println(“我是通过importSelector导入进来的service”);  

   }

}

通过ImportBeanDefinitionRegistar导入进来的

public class TulingDao {   

  public void testTulingDao() {       

  System.out.println(“我是通过ImportBeanDefinitionRegistrar导入进来tulingDao组件”);   

  }

}

测试结果:

Springboot自动装配原理_自动装配原理

 

1.3)spring底层条件装配的原理@Conditional

应用要求:比如我有二个组件,一个是TulingLog  一个是TulingAspect

而TulingLog 是依赖TulingAspect的 只有容器中有TulingAspect组件才会加载TulingLog

tulingLog组件  依赖TulingAspect组件

public class TulingLog {

}

tulingAspect组件

public class TulingAspect {

}

①:自定义条件组件条件 

public class TulingConditional implements Condition {  

   @Override     public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {   

      //容器中包含tulingAspect组件才返回Ture    

     if(conditionContext.getBeanFactory().containsBean(“tulingAspect”)){    

         return true;       

  }else{       

      return false;         }  

   }

}

                        ————————————-该情况下会加载二个组件————————————————-

@Bean   

  public TulingAspect tulingAspect() {     

    System.out.println(“TulingAspect组件自动装配到容器中”);     

    return new TulingAspect();     }        

       @Bean   

  @Conditional(value = TulingConditional.class)   

  public TulingLog tulingLog() {     

    System.out.println(“TulingLog组件自动装配到容器中”);    

     return new TulingLog();   

  }

                               ————————————-二个组件都不会被加载—————————————-

/*@Bean**/     

public TulingAspect tulingAspect() {      

   System.out.println(“TulingAspect组件自动装配到容器中”);   

      return new TulingAspect();  

   }             

  @Bean   

  @Conditional(value = TulingConditional.class)   

  public TulingLog tulingLog() {      

   System.out.println(“TulingLog组件自动装配到容器中”);    

     return new TulingLog();  

   }

  自动装配原理分析  从@SpringbootApplication入手分析

Springboot自动装配原理_自动装配原理

springboot自动装配流程图 

Springboot自动装配原理_自动装配原理

让我们仔细分析 

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports

public class AutoConfigurationImportSelector                                                                                                                                          implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,                                                          BeanFactoryAware, EnvironmentAware, Ordered {

@Override

public String[] selectImports(AnnotationMetadata annotationMetadata) {

          if (!isEnabled(annotationMetadata)) {

                  return NO_IMPORTS;

}

          AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader                                                                     .loadMetadata(this.beanClassLoader);

          AnnotationAttributes attributes = getAttributes(annotationMetadata);

          //去mata-info/spring.factories文件中 查询 EnableAutoConfiguration对于值

          List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);

          //去除重复的配置类,若我们自己写的starter 可能存主重复的

          configurations = removeDuplicates(configurations);                                                                                                                 Set<String> exclusions = getExclusions(annotationMetadata, attributes);                                                                                checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions);

         //根据maven 导入的启动器过滤出 需要导入的配置类

         configurations = filter(configurations, autoConfigurationMetadata);                                                                                           fireAutoConfigurationImportEvents(configurations, exclusions); return StringUtils.toStringArray(configurations);

     }

}

//去spring.factories 中去查询EnableAutoConfirution类

 private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {                                                   MultiValueMap<String, String> result = cache.get(classLoader);

                 if (result != null) {

                         return result;

                 }

                try {            

                     Enumeration<URL> urls = (classLoader != null ?                                                                                                                                        classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :                                                                                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));                                                        result = new LinkedMultiValueMap<>();

                       while (urls.hasMoreElements()) {

                               URL url = urls.nextElement();

                               UrlResource resource = new UrlResource(url);                                                                                                                         Properties properties = PropertiesLoaderUtils.loadProperties(resource);

                               for (Map.Entry<?, ?> entry : properties.entrySet()) {

                                        List<String> factoryClassNames = Arrays.asList(                                                                                                                                     StringUtils.commaDelimitedListToStringArray((String) entry.getValue()));                                                                 result.addAll((String) entry.getKey(), factoryClassNames);

                               }

                      }

                     cache.put(classLoader, result);

                     return result; }

catch (IOException ex) {

                    throw new IllegalArgumentException(“Unable to load factories from location [” +                                                                                     FACTORIES_RESOURCE_LOCATION + “]”, ex); } }

Springboot自动装配原理_自动装配原理 

然后我们分析RedisAutoConfiguration类

     导入了三个组件  RedisTemplate   StringRedisTemplate

     JedisConnectionConfiguration 

Springboot自动装配原理_自动装配原理

Springboot自动装配原理_自动装配原理

 Springboot自动装配原理_自动装配原理

Springboot自动装配原理_自动装配原理

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/171425.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何给自己心仪的人每天发送天气提醒消息

    如何给自己心仪的人每天发送天气提醒消息

    2021年9月18日
    61
  • 试用员工转正申请表怎么填_试用期转正申请500字

    试用员工转正申请表怎么填_试用期转正申请500字附件1:XXXX试用员工转正申请表XXXX试用员工转正申请表姓名张三部门研发部职务Java工程师学历大专毕业院校及时间XX大学2012.9-2015.7专业计算机信息管理试

    2022年8月3日
    11
  • ansys隐式显式算法区别_算力与算法的区别举例说明

    ansys隐式显式算法区别_算力与算法的区别举例说明2.4PIMPLE算法2.4.1速度的非线性耦合在2.1节中,我们曾对流动系统的压力速度耦合问题进行过讨论,实际上,在流动系统中除了压力和速度的耦合关系,我们还存在着另一种重要的耦合关系,速度的非线性耦合关系。当我们对速度进行求解时(例如求解动量预测方程),速度是未知量,因此对流项∇⋅(U⃗U⃗)\nabla\cdot(\vecU\vecU)∇⋅(UU)是一个未知量乘以未知量的结果,这样会使得原来呈线性的方程变为非线性方程(即未知数的最高次数从1变为2)。直接求解非线性系统的矩阵方程需要调用非线性

    2025年7月7日
    0
  • Oracle 904_oracle01017

    Oracle 904_oracle01017SQL>desceq_admin.its_earthquake_recover;名前NULL?型—————————————————————————–ORG_INF…

    2022年9月20日
    0
  • 计算机存储容量1tb等于多少,1tb等于多少mb(1tb等于多少gb)

    计算机存储容量1tb等于多少,1tb等于多少mb(1tb等于多少gb)1TB等于多少MB和多少GB?是电脑的硬盘!谢谢!1GB=1024MB(理论上)计算机存储信息的大小,最基本的单位是字节,一个汉字由两个字节组成,字母和数字由一个字节组成。容量的单位从小到大依次是:字节(B.1TB等于1024G。TB:太字节(Terabyte),计算机存储容量单位,也常用TB来表示。GB:吉字节(GB、Gigabyte,在中国又被称为吉咖字节或京字节或十亿字节或戟).1TB=…

    2022年5月25日
    117
  • Win10与Ubuntu 18.04双系统安装。(Win10引导Linux)[通俗易懂]

    Win10与Ubuntu 18.04双系统安装。(Win10引导Linux)[通俗易懂]作为菜鸟,为了满足我自己的求知欲,特别照着几篇大神教程装了一遍,给大家分享一下流程。1、win10安装(已安装请略过)1)系统U盘制作(参照微信公众号“软件安装管家”):http://mp.weixin.qq.com/s?__biz=MzIwMjE1MjMyMw==&amp;mid=2650199025&amp;idx=1&amp;sn=49b0d9b6d9f02b68223f7a9f913cde…

    2022年7月24日
    20

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号