springboot--16 SpringBoot深度实践(走向自动装配)

1.系列总览

SpringBoot的核心特性:

 

 

 

 

 

 

 2.自动装配

     2.1.SpringFrameWork的手动装配

           2.1.1Spring 模式注解装配

         

           

           自定义模式注解

            @Component派生性”   需要注意的是签名要保持一致

@Target(ElementType.TYPE)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface FirstLevelRepository {
    //签名保持一致
    String value() default "";
}

          使用这个注解:

package com.wx.springbootdemo.repository;

import com.wx.springbootdemo.annotation.FirstLevelRepository;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
@FirstLevelRepository(value = "myRepository")
public class MyRepository {
}

 测试@Component的派生注解是否成功

package com.wx.springbootdemo.bootstrap;

import com.wx.springbootdemo.repository.MyRepository;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
@ComponentScan(basePackages = "com.wx.springbootdemo.repository")
public class MainApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(MainApplication.class)
                .web(WebApplicationType.NONE)
                .run(args);
        MyRepository myRepository = applicationContext.getBean("myRepository", MyRepository.class);
        System.out.println(myRepository);

        //关闭上下文对象
        applicationContext.close();
    }
}

  ok,可以获得这个bean

@Component层次性 

  理解上面的派生性和层次性后,@SpringBootApplication注解也是从@Compoment派生和层次来的

 2.1.2 Spring @Enable 模块装配

Spring Framework 3.1 开始支持”@Enable 模块驱动。所谓模块是指具备相同领域的功能组件集合, 组合所形成一个独立

的单元。比如 Web MVC 模块、AspectJ代理模块、Caching(缓存)模块、JMXJava 管 理扩展)模块、Async(异步处

理)模块等。

   

 

  自定义Enable模块,分为注解驱动和接口资实现两种方式来实现自定义Enable模块

  基于注解实现的方式具体可以参考@EnableWebMv模块的实现,基于接口实现的方式具体可以参考@EnableCaching模块的实现。

 现在我们子当以一个HelloWorld模块,先基于注解驱动的方式来实现他。先参考一下@EnableWebMv模块的实现

 

参考上面,实现下面

 

ok,现在我可以测试一下这个模块开启后是否可用

package com.wx.springbootdemo.bootstrap;

import com.wx.springbootdemo.annotation.EnableHelloWorld;
import com.wx.springbootdemo.repository.MyRepository;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
@EnableHelloWorld
public class MainEnable {
    public static void main(String[] args) {

        ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(MainEnable.class)
                .web(WebApplicationType.NONE)
                .run(args);
        String helloWord = applicationContext.getBean("helloWord", String.class);
        System.out.println(helloWord);
        //
        applicationContext.close();
    }
}

 

接下来实现接口驱动的方式:

参考@EnableCaching

参考上面实现下面:

测试没有问题。实现接口的这种方式呢有弹性,可以自定义实现多个返回值

2.1.3 Spring 条件装配

 

  基于配置的方式@Profile实现多个整数相加的功能

package com.wx.springbootdemo.servcie;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
public interface CalculationService {
    public Integer sum(Integer ... values);
}

  

package com.wx.springbootdemo.servcie.imp;

import com.wx.springbootdemo.servcie.CalculationService;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
@Profile("java7")
@Service
public class Java7CalculationServiceImp implements CalculationService {
    @Override
    public Integer sum(Integer... values) {
        System.out.println("java7 for 循环实现");
        int sum = 0;
        for (Integer value : values) {
            sum += value;
        }
        return sum;
    }
}




package com.wx.springbootdemo.servcie.imp;

import com.wx.springbootdemo.servcie.CalculationService;
import org.apache.el.stream.Stream;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import java.util.Arrays;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
@Profile("java8")
@Service
public class Java8CalculationServiceImp implements CalculationService {
    @Override
    public Integer sum(Integer... values) {
        System.out.println("java8 lambda 循环实现");
        Integer reduce = Arrays.stream(values).reduce(0, Integer::sum);
        return reduce;
    }
}

 测试:

package com.wx.springbootdemo.bootstrap;

import com.wx.springbootdemo.servcie.CalculationService;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.util.Arrays;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
@ComponentScan(basePackages = "com.wx.springbootdemo.servcie.*")
public class MainConditionalAssembly {
    public static void main(String[] args) {

        ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(MainConditionalAssembly.class)
                .web(WebApplicationType.NONE)
                .profiles("java8")
                .run(args);
        CalculationService bean = applicationContext.getBean(CalculationService.class);
        Integer sum = bean.sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        System.out.println(sum);
        //
        applicationContext.close();
    }
}

 

接下来使用编程条件装配@Conditional来实现相同的功能,我们参考@ConditionalOnClass来实现一个@ConditionalOnSystemProperty,他的功能是判断属性是否满足系统的属性。

参看上面实现下面:我们这个注解的作用是判断条件是否和系统的值相等

package com.wx.springbootdemo.condition;

import org.springframework.context.annotation.Conditional;

import java.lang.annotation.*;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({OnSystemPropertyCondition.class})
public @interface ConditionalOnSystemProperty {
   String value() default "";

   String name() default "";
}

 

package com.wx.springbootdemo.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.Map;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
public class OnSystemPropertyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        Map<String, Object> attributes =
                annotatedTypeMetadata.getAnnotationAttributes(ConditionalOnSystemProperty.class.getName());
        String name = String.valueOf(attributes.get("name"));
        String value = String.valueOf(attributes.get("value"));
        String name1 = System.getProperty(name);
       return name1.equals(value);

    }
}

 使用,当条件满足,那么Bean会加载,打印输出,如果条件不满足就找不到这个Bean

package com.wx.springbootdemo.bootstrap;

import com.wx.springbootdemo.condition.ConditionalOnSystemProperty;
import com.wx.springbootdemo.repository.MyRepository;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

/**
 * User: Mr.Wang
 * Date: 2019/10/21
 */
public class MainConditional {

    @Bean
    @ConditionalOnSystemProperty(name = "user.name", value = "wangxiang")
    public String helloWorld() {
        return "I'm iron man";
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(MainConditional.class)
                .web(WebApplicationType.NONE)
                .run(args);
        String bean = applicationContext.getBean(String.class);
        System.out.println(bean);
        applicationContext.close();
    }
}

 

 

 2.2.SpringBoot的自动装配

     

     

   实现自定义的自动装配,实现HelloWorld的自动配置,之前不是有什么模式装配,@Enable模块装配,条件装配吗。

   现在用这些来实现HelloWorld模块的自动装配。

   实现需要三步走

  第一步激活自动装配,只有激活这个自动装配了,Spring的工厂才会去读取配置的spring.factories 文件来自动装配,

  

  第一步激活自动装配以后就会Spring的工厂SpringFactoriesLoader 就会加载这个文件,第二步就是实现自动装配

 

 然后他会通过反射去创建这些配置类

配置累的编写参考:WebMvcAutoConfiguration

参考上面:

第三步就是配置自动装配实现

测试:

ok没有问题

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时空恋旅人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值