SpringBoot学习二

(*告知读者:本文章内容属于本人学习中笔记,若有错误或不当之处欢迎留言指出)

SpringBoot基于Spring开发应用程序,那么学习SpringBoot就不能少去了解Spring的知识

一.Spring的两大核心理念:控制反转(Inversion of Control)和面向切面编程(Aspect Oriented Programming)

1.控制反转(Ioc):spring管理bean的容器,可以理解为Ioc容器,例如Web容器一样的东西。它有两个基本功能:

a.通过描述管理Bean,包括发布并且获取Bean

b.通过描述来完成Bean之间的依赖关系,则过程叫做依赖注入(Dependency Injection)

1.1  所有Ioc容器都需要实现的一个顶级接口BeanFactory,它的源码如下:

public interface BeanFactory {
    // 前缀
    String FACTORY_BEAN_PREFIX = "&";
    
    // 多个获取Bean的方法
    Object getBean(String var1) throws BeansException;

    <T> T getBean(String var1, Class<T> var2) throws BeansException;

    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;

    <T> ObjectProvider<T> getBeanProvider(Class<T> var1);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType var1);

    // 是否包含Bean
    boolean containsBean(String var1);

    // 是否是单例模式
    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;

    // 是否是原型
    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

    // 是否类型匹配
    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;

    // 获取Bean的类型
    @Nullable
    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;

    @Nullable
    Class<?> getType(String var1, boolean var2) throws NoSuchBeanDefinitionException;

    // 获取Bean的别名
    String[] getAliases(String var1);
}

1.2  接下来就是怎样在Ioc容器里装配Bean,SpringBoot基于注解开发应用程序,所以在此也用注解实现装配Bean

a.通过@Bean注解装配

/**
 * name的值相当于在Ioc容器为Bean取的名字
 * 在Ioc容器可通过getBean(name)来获取Bean
 */
@Bean(name="myUser")
public User getUser(){
    User user = new User();
    user.setId(1);
    user.setName("张三");
    return user;
}

b.通过@Component注解装配

@Component("myUser")
public class User {
    @Value("123")
    private int id;
    @Value("李四")
    private String name;
}

c.还可通过@ComponentScan注解定义扫描的包 ,注解源码如下:

// 表示生命周期在运行时有效
@Retention(RetentionPolicy.RUNTIME)
// 表示该注解用于什么上面,此值表示用在类上
@Target({ElementType.TYPE})
@Documented
// 是否可重复使用
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    // 定义扫描的包
    @AliasFor("basePackages")
    String[] value() default {};
    // 定义扫描的包 value与basePackages同作用
    @AliasFor("value")
    String[] basePackages() default {};
    
    // 定义扫描的类
    Class<?>[] basePackageClasses() default {};
    
    // Bean name生成器
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    // 作用域解析器
    Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;

    // 作用域代理模式
    ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

    String resourcePattern() default "**/*.class";

    // 是否启用默认的过滤器
    boolean useDefaultFilters() default true;

    // 当满足过滤器条件时扫描
    ComponentScan.Filter[] includeFilters() default {};

    // 不满足过滤器条件时扫描
    ComponentScan.Filter[] excludeFilters() default {};

    // 是否延迟初始化 懒加载
    boolean lazyInit() default false;

    // 定义过滤器
    @Retention(RetentionPolicy.RUNTIME)
    @Target({})
    public @interface Filter {
        
        // 过滤器类型 可以按注解或者正则式过滤
        FilterType type() default FilterType.ANNOTATION;

        // 过滤的类
        @AliasFor("classes")
        Class<?>[] value() default {};
        
        // 过滤的类
        @AliasFor("value")
        Class<?>[] classes() default {};
        
        // 匹配方式过滤
        String[] pattern() default {};
    }
}

1.3  Ioc的另外一个功能,依赖注入(Dependency Injection)

a.注解@Autowired

public class User {
    
    @Autowired
    private MobilePhone mobilePhone;

    public useMobilePhone(){
       this.mobilePhone.use();
    }

    public static void main(String[] args) {
        User user = new User();
        user.useMobilePhone();
    }

}

public interface MobilePhone {
    void use();
}

@Component
public class HUAWEIMobilePhone implements MobilePhone {
    public void use(){
        System.out.println("使用华为手机");
    }
}

@Component
public class AppleMobilePhone implements MobilePhone {
    public void use(){
        System.out.println("使用苹果手机");
    }
}

@Component
public class XiaoMIMobilePhone implements MobilePhone {
    public void use(){
        System.out.println("使用小米手机");
    }
}

此时手机有不同类型的手机,通过@Autowired注解进行注入就会报错

此时可引入注解@Primary和注解@Qualifier解决,代码如下

@Component
//此注解表示优先注入此类型的Bean
@Primary
public class HUAWEIMobilePhone implements MobilePhone {
    public void use(){
        System.out.println("使用华为手机");
    }
}

@Component
public class AppleMobilePhone implements MobilePhone {
    public void use(){
        System.out.println("使用苹果手机");
    }
}

@Component
public class XiaoMIMobilePhone implements MobilePhone {
    public void use(){
        System.out.println("使用小米手机");
    }
}

但是三个类型都加@Primary注解则还是会报错,则@Qualifier派上用场,此注解可通过Bean的名字进行注入,

例如:@Qualifier("appleMobilePhone") 

public class User {
    
    @Autowired
    @Qualifier("appleMobilePhone")
    private MobilePhone mobilePhone;

    public useMobilePhone(){
       this.mobilePhone.use();
    }

    public static void main(String[] args) {
        User user = new User();
        user.useMobilePhone();
    }

}

总结:Ioc容器为Spring管理Bean的容器,用@Bean,@Component,@ComponentScan注解可装配你的Bean。

@Autowired用来实现依赖注入,@Primary和@Qualifier来消除歧义性 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值