Spring全家桶 ~ 你应该知道的知识点

  • InitializingBean接口
    package org.springframework.beans.factory;
    public interface InitializingBean {
    	void afterPropertiesSet() throws Exception;
    }
    这个接口就这一个方法,这个接口在一些中间件中肯定会涉及到,因为它独特的魅力,首先看它bean实例化执行的位置:

    一般什么时候需要用到实现这个接口呢?当你需要给bean的属性设置值,是不是感觉等于没说?这么说吧:写代码的时候可以利用这一个方法,来触发一些任务,例如,轮询数据库获取数据;初始化一些参数;触发一些周期性事件等。特别地,当项目中需要从数据库中获取不变配置项,可以利用该方法只在Java Bean启动的时候调用的特性,减少对数据库的访问量。


     
  • Aware接口
    比如用的最多的:ApplicationContextAware、BeanFactoryAware、XXXAware......
    一般什么时候需要用到实现这个接口呢?当你的bean希望能持有XXX作为属性的时候,你就实现XXXAware,比如你想在Bean中定义一个ApplicationContext对象,你需要初始化它,那么就可以实现ApplicationContextAware,在Spring容器加载Bean的过程中,就会调用:如下示例,实现ApplicationContextAware接口的setApplicationContext方法,Spring容器会在适当的适合调用这个setApplicationContext方法,将ApplicationContext的引用传递给下面定义的ApplicationContextHolder的applicationContext属性。XXXAware什么时候触发执行呢》参考上面的图吧,图的左边:检测Aware相关接口并.......
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    public class ApplicationContextHolder implements ApplicationContextAware {
    	private static ApplicationContext applicationContext;
    	@Override
    	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    		ApplicationContextHolder.applicationContext = applicationContext;
    	}
    	public static ApplicationContext getApplicationContext() {
    		return applicationContext;
    	}
    }


     

  • FactoryBean接口
    package org.springframework.beans.factory;
    import org.springframework.lang.Nullable;
    public interface FactoryBean<T> {
    	@Nullable
    	T getObject() throws Exception;
    
    	@Nullable
    	Class<?> getObjectType();
    
    	default boolean isSingleton() {
    		return true;
    	}
    }
    一般什么时候需要用到实现这个接口呢?FactoryBean接口的核心就在于通过getObject方法可以获取的是它所生产的对象,所以我们在Proxy创建代理对象的时候就比较方便。还有一些bean,如果通过配置的方式,会显得比较麻烦和复杂,那么这时候适当的采用编码方式在某些场合下还是挺不错的Spring容器默认加载bean是单例的,如果你希望你写的一个bean不是单例,除了配置文件设置外,现在流行的都是实现这个接口的isSingleton方法,返回false即可。此接口,因能力有限,无法感觉其最大作用,读者自YY。

     
  • SmartLifecycle接口
    public interface SmartLifecycle extends Lifecycle, Phased {
    	int DEFAULT_PHASE = Integer.MAX_VALUE;
    	default boolean isAutoStartup() {
    		return true;
    	}
    	default void stop(Runnable callback) {
    		stop();
    		callback.run();
    	}
    	@Override
    	default int getPhase() {
    		return DEFAULT_PHASE;
    	}
    }
    
    public interface Lifecycle {
    	void start();
    	void stop();
    	boolean isRunning();
    }
    
    public interface Phased {
    	//Return the phase value of this object.
    	int getPhase();
    }
    一般什么时候需要用到实现这个接口呢?这位博主说的更好:如果业务上需要在spring容器启动和关闭的时候做一些操作,比如启动netty的服务端、优雅的关闭服务端。从上述列举中可以看出,感知容器变化的能力最终来自Lifecycle,而SmartLifecycle只是Lifecycle的增强版,可以自定义优先级(getPhase),自主决定是否随容器启动(isAutoStartup),以及停止时能接受一个runnable对象(stop(Runnable))https://blog.csdn.net/boling_cavalry/article/details/82051356



     
  • ApplicationListener、ApplicationEventPublisher接口
    可以监听某个事件event,监听的event类型就是接口中的E,当有人publish事件类型E的时候,实现了ApplicationListener并且监听类型为E的类就会触发onApplicationEvent方法。Spring内部有大量的内置事件,看源码能感受到。
    package org.springframework.context;
    import java.util.EventListener;
    public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
    	void onApplicationEvent(E event);
    }
    
    public interface ApplicationEventPublisher {
    	void publishEvent(ApplicationEvent event);
    	void publishEvent(Object event);
    }
    此接口应用也极其广泛,当你想在某些操作发生的时候,触发某些操作,可以用此接口。比如我们程序员,当你知道你家里发财了,有10个亿的时候,你肯定第一想知道,并且立马辞职不干了~
    //定义一个事件类型
    import org.springframework.context.ApplicationEvent;
    public class MoneyGetEvent extends ApplicationEvent {
        public MoneyGetEvent(Object source) {
            super(source);
        }
    }
    
    //发布事件
    import org.springframework.context.ApplicationEventPublisher;
    import org.springframework.context.ApplicationEventPublisherAware;
    public class PublishEventClass  implements ApplicationEventPublisherAware {
        private ApplicationEventPublisher eventPublisher;
        /**
         * 实现了ApplicationEventPublisherAware接口,容器加载该bean的时候会调用此setApplicationEventPublisher方法,
         * 给该bean的eventPublisher属性赋值,此对象用来发布事件,发布后,会触发对此事件类型感兴趣的bean的
         */
        @Override
        public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
            this.eventPublisher = eventPublisher;
        }
        //当调用该方法的时候,会触发MoneyGetEventListener的onApplicationEvent方法
        public void moneyGet() {
           eventPublisher.publishEvent(new MoneyGetEvent("儿子,家里拆迁分了10个亿,还是美元"));
        }
    }
    
    //监听事件
    import org.springframework.context.ApplicationListener;
    import org.springframework.stereotype.Component;
    @Component
    public class MoneyGetEventListener implements ApplicationListener<MoneyGetEvent> {
        @Override
        public void onApplicationEvent(MoneyGetEvent event) {
            System.out.println("老板,我摊牌了,我是亿万富翁,上你个屁班!");
        }
    }
  • 自定义Spring Boot Start  
     

    spring-boot-starter:spring-boot可以省略众多的繁琐配置,它的众多starter可以说是功不可没。例如spring-boot中集成redis,只需要pom.xml中引入spring-boot-starter-data-redis,配置文件中加入spring.redis.database等几个关键配置项即可,常用的starter还有spring-boot-starter-web、spring-boot-starter-test、spring-boot-starter-jdbc,相比于传统的xml配置可以说是大大减少了集成的工作量。SpringBoot启动时会找到starter jar包中的resources/META-INF/spring.factories文件,根据spring.factories文件中的配置,找到需要自动配置的类,读取例如:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.test.springboot.starter.helloworld.configuration.MyAutoConfiguration 

    指定的Configuration,根据Configuration上的Conditional条件自动创建bean,注入容器(spring.factories并非是必须的,也可以在启动类上添加如下注解进行自动配置:@ImportAutoConfiguration({MyAutoConfiguration.class}))
    精彩示例:https://blog.csdn.net/boling_cavalry/article/details/82956512
    常见注解:

    @ConditionalOnBean:当容器中有指定的Bean的条件下
    @ConditionalOnClass:当类路径下有指定的类的条件下
    @ConditionalOnExpression:基于SpEL表达式作为判断条件
    @ConditionalOnJava:基于JVM版本作为判断条件
    @ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
    @ConditionalOnMissingBean:当容器中没有指定Bean的情况下
    @ConditionalOnMissingClass:当类路径下没有指定的类的条件下
    @ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
    @ConditionalOnProperty:指定的属性是否有指定的值
    @ConditionalOnResource:类路径下是否有指定的资源
    @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean
    @ConditionalOnWebApplication:当前项目是Web项目的条件下

     
  • Spring的事务管理器
  • ApplicationContextInitializer


    TODO......
发布了142 篇原创文章 · 获赞 345 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/zhengchao1991/article/details/99608768