SpringBoot源码浅读

一注解
1.@EnableAutoConfiguration 会从classpath中搜索所有的(包含外部jar)META-INF/spring.factories配置文件,然后将org.springframework.boot.autoconfiguration.EnableAutoConfiguration key对应的配置添加到spring容器中

该文件的value值可以时@configuration类,也可以是普通的类。都可以在其他项目中进行bean对象的获取。

从而完成spring对外部jar包中类的加载。

内部实现的因素:
ImportSelector 该接口的返回值都会被纳入spring容器的管理之内
SpringFactoryLoader可以从classpath中搜索所有的META-INF/spring.factories配置文件,并加载所有配置项

如果当前项目配置spring.boot.enableautoconfiguration=false,则以上所述也是无法正常使用的。此属性默认为true

可以在@AutoConfiguration中使用exculd=.class/类全名 排除不进行自动加载的类

2.@EnableConfigurationProperries 该注解的作用是将配置文件中的属性值加载到具体的实体类对象中

3.@EnableAsync 启动异步执行,在需要异步执行的方法上面添加注解 @Async

4.@Component 该注解会默认将当前类加载到Spring容器中,所以无需再在@Configuration配置类中重新配置一个bean,如果配置之后,不可为类名首字母小写

5.动态适配需要装配的bean对象
① 使用@Ennable* + @Import注解 此种方式相当于被动添加,也就是说Spring容器会自动获取到对应的bean并进行添加

@Enable* @Import() 注解 该注解的参数bean,可以被加载到bean容器中
@ennable 该注解需要结合对应的实现ImportSelector接口的对应类,并将该类使用@Import注解导入自定义的@ennable*注解上。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportSelect.class)
public @interface EnnableLog {
    String name();
}

//返回值为一个String数组   返回的对象都会交予Spring容器进行托管
//也可以在其方法中获取到指定注解的一些信息,从而进行一系列自定义配置
public class MyImportSelect implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        System.out.println(annotationMetadata.getAllAnnotationAttributes(EnnableLog.class.getName()));;
        return new String[]{};
    }
}

@EnnableLog(name = "CYAN")

在selectImports方法中可以直接获取该注解的参数值,即:CYAN

②实现InportBeanDefinitionRegistrar接口,该种方式属于主动添加
实现该接口之后需要重写其registerBeanDefinitions()方法。
使用的时候,可以选择Import(MyImportBeanDefinitionRegistrar.class)直接将该类添加到程序入口类上,应该也可以直接@Component将其添加到SPring容器中。

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        Map<String, Object> arr = annotationMetadata.getAnnotationAttributes(Logecho.class.getName());
        //packages   为Logecho.class注解对象的属性的属性名
        String[] ar = (String[]) arr.get("packages");
        List<String> packages = Arrays.asList(ar);
        //此处可以获取到对应的Logecho.class注解添加的属性值
        System.out.println("**************"+packages);
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(LogBeanPostProcessor.class);

        beanDefinitionBuilder.addPropertyValue("packages", packages);

        beanDefinitionRegistry.registerBeanDefinition(LogBeanPostProcessor.class.getName(),beanDefinitionBuilder.getBeanDefinition());
    }

六/EnvironmentPostProcessor接口
将该接口的实现类添加到Spring容器中,可以实现加载非项目中文件配置属性内容

@Component
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        try{
            InputStream inputStream = new FileInputStream("E:\\spring.properties");
            Properties prop = new Properties();
            prop.load(inputStream);
            PropertiesPropertySource propertiesPropertySource
                    = new PropertiesPropertySource("my",prop);
            environment.getPropertySources().addLast(propertiesPropertySource);
        }catch (IOException e){

        }
    }
}

二.事件的创建和监听
1.自定义事件:
继承ApplicationEvent抽象类
2.自定义监听器:
实现ApplicationListener接口
3.添加监听器进spring管理
SpringApplication.addListener()
直接在实现了ApplicationListener的监听器上面添加@Component注解将监听器交予Spring容器管理
在application.properties中配置属性context.listener.classes=全类名进行监听器的发布
直接创建一个监听器的类(无需实现ApplicationListener),并交予spring容器进行管理,声明一个参数为需要监听的事件(所有该事件以及该事件的子类都会被监听,不可没有参数)的方法,如果为Object则会监听spring的所有事件。并在方法上添加注解@EventListener
4.发布事件:
ApplicationContext.pushlishEvent() 详细参照EventListenerMethodProcessor,EventListenerFactory

三.Condition接口

@Conditional 基于条件的自动配置,一般配合Condition的实现类一起使用,只有一个或多个接口的实现类全部返回为true才会进行对应bean的装配。否则不装配,可以在单个方法上面也可以在配置类上面。

该接口提供了SPring的自动化配置,重写该接口的matches方法,可以自定义选择加载一些配置文件。

//当该方法的返回值为true时,才会加载对应的bean
@public class GBKCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        String e = System.getProperty("file.encoding");
        if (e != null) {
            return "gbk".equals(e.toLowerCase());
        }
        return false;
    }
}

当然此时需要在配置类的对应bean上添加@Conditional(GBKCondition.class)

@SpringBootConfiguration
public class EncodingConvertConguration {
    //Convert 为不同加载文件的基类
    @Bean
    @Conditional(UTF8Condition.class)
    public Convert UTF8(){
        return new UTF8EncodingConvert();
    }
    @Bean
    @Conditional(GBKCondition.class)
    public Convert GBK(){
        return new GBKEncodingConvert();
    }
}

四.BeanPostProcessor接口
实现该接口的类,加入SPringle容器后,在bean创建未赋值之前调用其postProcessBeforeInitialization(),在赋值之后调用postProcessAfterInitialization(),可以借此做一些自定义的操作。

五 自定义扫描注解包内的bean对象

@SpringBootApplication
//配置的需要扫描的包
@Logecho(packages = {"com.example.log.Dao","com.example.log.Bean"})
@EnableAutoConfiguration
public class LogApp {
    public static void main(String[] args) {
        ConfigurableApplicationContext context =
                SpringApplication.run(LogApp.class, args);
        //获取对应的包下的bean        
        System.out.println(context.getBean(Dog.class));;

        System.out.println(context.getBean(Runnable.class));
    }
}

//该类会在bean加载的过程中进行执行
public class LogBeanPostProcessor implements BeanPostProcessor {

    private List<String> packages;

    public List<String> getPackages() {
        return packages;
    }

    public void setPackages(List<String> packages) {
        this.packages = packages;
    }

    //该方法的返回的bean都会被实例化
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        for (String aPackage : packages) {
            if (bean.getClass().getName().startsWith(aPackage)) {
                System.out.println("==================="+bean.getClass().getName());
            }
        }
        return bean;
    }

     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }



@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
//导入的配置类ImportBeanDefinitionRegistrar,在其中扫描该注解的packages属性,并将该
@Import(MyBeanRegister.class)
public @interface Logecho {

    String[] packages();

}

//主动加载bean
public class MyBeanRegister implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        Map<String, Object> arr = annotationMetadata.getAnnotationAttributes(Logecho.class.getName());
        //获取Logecho.class配置的packages的属性值
        String[] ar = (String[]) arr.get("packages");
        List<String> packages = Arrays.asList(ar);
        System.out.println("**************"+packages);
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(LogBeanPostProcessor.class);

        beanDefinitionBuilder.addPropertyValue("packages", packages);

        beanDefinitionRegistry.registerBeanDefinition(LogBeanPostProcessor.class.getName(),beanDefinitionBuilder.getBeanDefinition());
    }
}













六 主要的类

FactoryBean接口 实现该接口,重写该接口的三个方法,getObject() 返回一个需要返回的bean的对象, 第二个方法直接返回该类的类型,第三个设置是否为单例
在配置类中配置返回对应的FactoryBean对象即可获取到对应的bean实例。
也可以在配置类中直接创建一个返回bean的方法,参数设置为对应的facrotyBEAN,一个返回对应的factoryBean的方法,此时,会自动将配置类中的factorybean对象作为参数传递给真正需要返回的bean的配置方法中

指定类的初始化和销毁方法

@Bean(initMethod="",destoryMethod="") 可以指定初始化和销毁方法

也可以在对应的初始化和销毁方法上添加注解@PostConstruct和@PreDestory注解
也可以使用该类实现InitalizingBean,DisposableBean接口,并重写对应的afterPropertiesSet()和destory()方法

标注注解 @Repository一般标注在数据访问层上面 表示该类为bean交予spring容器托管
@Primary 配置类的注解,表示如果在注入时,发现多个bean,则优先加载标注的bean

BeanPostProcessor接口 Bean的后置处理器 会在每个Bean初始化的时候都执行
第一个方法会在bean初始化完成未配置属性值之前执行 
第二个方法会在bean属性配置完成之后执行  
可以在两个方法中进行一些额外的属性配置等操作  

Aware接口经常结合BeanPostProcessor接口进行使用,判断是否是对应aware对象并进行对应的操作。

BeanFactoryPostProcessor接口 在bean容器初始化之后进行执行 旨在SPring容器储时化之后触发一次,在BeanPostProcessor执行之前进行执行
实现该接口的类也需要添加到Spring容器之中  
BeanDefinitionRegistryPostProcessor 接口
实现该接口可以拿到BeanDefinitionRegistry对象,从而进行动态bean的装配
需要将该类添加到Spring容器中
BeanDefinitionRegistry 实现该接口可以动态的实现bean的装配

BeanDefinitionBuiler.rootBeanDefinition(?.class).getBeanDefinition();
给对应的bean对象添加属性
BeanDefinitionBuiler.rootBeanDefinition(?.class).addPropertyValue("","");

EnvironmentPostProcessor

实现该类可以实现对外部配置文件的加载
Properties prop = new Properties();
InputStream is = new FileInputStream(“c:/asdada.sadada”);
prop.load(is);
PropertiesPropertySource ps = new PropertiesProperty("",prop);
environment.getPropertySources().addLast(ps);

这种情况需要在META-INF 下配置EnvironmentPostProcessor全类名=实现类的全类名

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值