spring

@SpringBootApplication
SpringBoot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就会运行这个类的main方法来启动SpringBoot项目。

########################################################################

那@SpringBootApplication注解到底是什么呢,点进去看看:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration 允许在上下文中注入额外的bean 或导入其它配置类
@EnableAutoConfiguration 启动springboot的自动配置机制
@ComponentScan( 扫描被@Component (@Service,@Controller)注解的bean,注解默认会
扫描启动类所在的包下所有的类,可以自动以不扫描某些类
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
}

########################################################################
SpringBootConfiguration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
String value() default “”;
}

说明Spring的配置类也是Spring的一个组件。

#########################################################################
EnableAutoConfiguration 这个注解是开启自动配置的功能。

@EnableAutoConfiguration 是实现自动装配的重要注解,自动装配核心功能的实现实际是通过EnableAutoConfigurationImportSelector 类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
}

-----------------------------------start----------------------------------------
先看看@AutoConfigurationPackage注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
这个注解是自动配置包,主要是使用的@Import来给Spring容器中导入一个组件 ,这里导入的是Registrar.class。

@Order(-2147483648)
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}

public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
	AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
}

}

查询结果:
(new AutoConfigurationPackages.PackageImport(metadata)).getPackageName() —> com.hikvision.admin.server

说白了就是将主配置类(即@SpringBootApplication标注的类)的所在包及子包里面所有组件扫描加载到Spring容器。
所以包名一定要注意。
-----------------------------------end ----------------------------------------

@Import注解就是给Spring容器中导入一些组件,这里传入了一个组件的选择器:AutoConfigurationImportSelector。

里面有一个selectImports方法,将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中。

EnableAutoConfigurationImportSelector 这个类实现了 ImportSelector接口,也就实现了接口中的selectImports方法。
该方法主要用于获取所有符合条件的类的全限定类名,这些类需要被加载到IOC容器中
public class AutoConfigurationImportSelector implements DeferredImportSelector{
}

public interface DeferredImportSelector extends ImportSelector {
}

public interface ImportSelector {
String[] selectImports(AnnotationMetadata var1);

}

								无状态对象和有状态对象

无状态对象,没有状态,只有只读属性,没有可写属性
有状态就是有数据存储功能。有状态对象(StatefulBean),就是有实例变量的对象,可以保存数据,是非线程安全的。
在不同方法调用期间不保存任何状态。因此有状态对象用于多例

无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象.不能保存数据,是不变类,是线程安全的。
所以在开发中要多使用无状态对象。无状态多用于是单例

								BeanPostProcessor

**

  • 应用上下文工具类

  • @author liuhan10
    */
    @Component
    public class ApplicationContextUtil implements StaticUtilInitializer {

    private static ApplicationContext context;

    public ApplicationContextUtil(@Autowired ApplicationContext context){
    ApplicationContextUtil.context=context;
    }

    public static T getBean(Class t) {
    return context.getBean(t);
    }

    public static String getProperty(String key) {
    return context.getEnvironment().getProperty(key);
    }

    public static T getBeanByName(String beanName, Class t) {
    return context.getBean(beanName, t);
    }
    }

/**

  • 实现这个接口的Bean会优先加载,适用于依赖Spring应用上下文中其他Bean的静态工具类

  • @author liuhan10
    */
    public interface StaticUtilInitializer extends BeanPostProcessor {

    @Override
    default Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException{
    return var1;
    }

    @Override
    default Object postProcessAfterInitialization(Object var1, String var2) throws BeansException{
    return var1;
    }
    }

postProcessBeforeInitialization 方法中处理标记接口,在 postProcessAfterInitialization 中处理代理 beans。
BeanPostProcessor接口中定义了两个方法,其中方法postProcessBeforeInitialization()将在一个bean被完全初始化前进行回调,
此时对应的bean已经实例化了,但是对应的属性注入等还没有进行,即在调用InitializingBean的
afterPropertiesSet()方法或bean对应的init-method之前;而方法postProcessAfterInitialization()
将在bean被完全初始化后进行回调,此时对应的依赖注入已经完成,即在调用InitializingBean的afterPropertiesSet()方法
或对应init-method方法之后。两个方法的参数以及返回值对应的意义都是一样的,其中参数bean表示当前状态的bean,
参数beanName表示当前bean的名称,而方法对应的返回值即表示需要放入到bean容器中的bean,
所以用户如果有需要完全可以在这两个方法中对bean进行修改,即封装自己的bean进行返回。

BeanPostProcessor <------InstantiationAwareBeanPostProcessor <------SmartInstantiationAwareBeanPostProcessor

public class User {
@Autowired
private UserExt ext;
private String id;

public User() {
}
//其他

}

public class UserExt {
@Autowired
private User user;
private String name;

public UserExt() {
}
//其他

}

InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation - user
在实例化目标bean之前应用此BeanPostProcessor。
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation - user
在bean实例化之后,通过构造函数或工厂方法,但在Spring属性填充(来自显式属性或自动装配)之前执行操作。
InstantiationAwareBeanPostProcessor#postProcessProperties - user
在工厂将它们应用于给定bean之前对给定属性值进行后处理,不需要属性描述符。
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation - userExt
在实例化目标bean之前应用此BeanPostProcessor。
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation - userExt
在bean实例化之后,通过构造函数或工厂方法,但在Spring属性填充(来自显式属性或自动装配)之前执行操作。
InstantiationAwareBeanPostProcessor#postProcessProperties - userExt
在工厂将它们应用于给定bean之前对给定属性值进行后处理,不需要属性描述符。
SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference - user
获取早期访问指定bean的引用,通常用于解析循环引用。
BeanPostProcessor#postProcessBeforeInitialization - userExt
在任何bean初始化回调(如InitializingBean afterPropertiesSet 或自定义init方法)之前,将此BeanPostProcessor应用于给定的新bean实例。
BeanPostProcessor#postProcessAfterInitialization - userExt
在任何bean初始化回调(如InitializingBean afterPropertiesSet 或自定义init方法)之后,将此BeanPostProcessor应用于给定的新bean实例。
BeanPostProcessor#postProcessBeforeInitialization - user
在任何bean初始化回调(如InitializingBean afterPropertiesSet 或自定义init方法)之前,将此BeanPostProcessor应用于给定的新bean实例。
BeanPostProcessor#postProcessAfterInitialization - user
在任何bean初始化回调(如InitializingBean afterPropertiesSet 或自定义init方法)之后,将此BeanPostProcessor应用于给定的新bean实例。

						beanFactoryPostProcessor
  1. beanFactoryPostProcessor接口可以在bean未被实例化之前获取bean的定义即配置元数据,然后根据需要进行更改。
  2. beanFactoryPostProcessor里有方法 void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; 此方法可以通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。
  3. 可以在spring配置文件中定义多个beanFactoryPostProcessor,执行顺序按照定义顺序执行,也可以根据order属性自己定义执行顺序。

public class FactoryPostProcessor implements BeanFactoryPostProcessor {

@Override
public void postProcessBeanFactory(
        ConfigurableListableBeanFactory configurableListableBeanFactory)
        throws BeansException {
    System.out.println("******调用了BeanFactoryPostProcessor");
    String[] beanStr = configurableListableBeanFactory
            .getBeanDefinitionNames();
    for (String beanName : beanStr) {
        if ("beanFactoryPostProcessorTest".equals(beanName)) {
            BeanDefinition beanDefinition = configurableListableBeanFactory
                    .getBeanDefinition(beanName);
            MutablePropertyValues m = beanDefinition.getPropertyValues();
            if (m.contains("name")) {
                m.addPropertyValue("name", "赵四");
                System.out.println("》》》修改了name属性初始值了");
            }
        }
    }
}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值