Spring-IoC系列——装配bean

我们定义一个user类:

@Data
@Builder
public class User {
    private Long id;
    private String name;
}

然后再定义一个java配置文件AppConfig:

@Configuration
public class AppConfig {

    @Bean
    public User user(){
        return User.builder().id(1L).name("谢飞").build();
    }
}

这里注意@Configuration,这是代表这个是一个java配置文件,spring的容器会根据它来生成IoC容器去装配bean,@Bean代表将user方法返回的pojo装配到ioc容器中,做好了这些就可以使用

AnnotationConfigApplicationContext来构建自己的ioc容器。
    @Test
    public void test(){
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
        User user = ctx.getBean(User.class);
        log.info(user.toString());
    }

运行结果: 

这个只是最简单的方法,而且注解@bean也不是唯一创建bean的方法。

从上面方法发现使用如果一个个的使用注解@bean注入到spring ioc容器是一件很麻烦的事情,好在spring还允许我们使用扫描装配bean到ioc容器,使用到的注解是@Component和@ComponentScan .

@Component是标记哪个类被扫描进入ioc容器,而@ComponentScan则是标明采用何种策略去扫描装配bean。

user:

@Component
@Data
public class User {

    @Value("2")
    private Long id;
    @Value("谢飞2")
    private String name;
}
AppConfig:
@Configuration
@ComponentScan
public class AppConfig {
}

这里加入@ComponentScan,意味着它会进行扫描,但只会扫描类AppConfig所在的当前包和其子包

测试:

扫描二维码关注公众号,回复: 6792919 查看本文章
    @Test
    public void test(){
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
        User user = ctx.getBean(User.class);
        log.info(user.toString());
    }

效果:

 @ComponentScan还允许我们自定义扫描的包

看源码:

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.annotation.AliasFor;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
//在一个类中可重复定义
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    //定义扫描的包
    @AliasFor("basePackages")
    String[] value() default {};
    //定义扫描的包
    @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 {};
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36850813/article/details/94731787