javascript
Spring注解驱动
文章目錄
- SpringBoot注解驅(qū)動(dòng)
- SpringBoot的事件監(jiān)聽
- 關(guān)于Spring *PostProcessor的總結(jié)
- 幾種*Aware反注入的實(shí)現(xiàn)
SpringBoot注解驅(qū)動(dòng)
SpringBoot的事件監(jiān)聽
事件監(jiān)聽三大步。首先創(chuàng)建一個(gè)事件,然后創(chuàng)建一個(gè)監(jiān)聽器,再創(chuàng)建一個(gè)事件發(fā)布類。
事件的監(jiān)聽是在bean創(chuàng)建完成之后執(zhí)行的,refresh()的最后一步執(zhí)行:
事件類:事件類要繼承ApplicationEvent這個(gè)抽象類,抽象類可以通過匿名內(nèi)部類實(shí)現(xiàn)(如果沒有抽象方法則大括號(hào)可以為空)
創(chuàng)建監(jiān)聽類:監(jiān)聽類繼承ApplicationListener,泛型指定固定類型。
默認(rèn)的Object source只有g(shù)etSource()方法。可以添加其他屬性(比如message)。
發(fā)布事件:事件的發(fā)布需要調(diào)用容器ApplicationContext,通過其publishEvent(),參數(shù)可以是ApplicationEvent或者自己設(shè)定的其他Event類。
/*** @author Hanxiaohan* @date 2021/03/19 15:50* @since 1.0* <p>Copyright: Copyright (c) 2021</p>*/ @Component public class EventPublisher {@Resourceprivate Ginger ginger;@AutowiredApplicationContext applicationContext;public void publish(String message){applicationContext.publishEvent(new SelfEvent(ginger,ginger.toString()+ message));}}本示例使用了一個(gè)普通bean作為source
@Component public class Ginger {@Value("China")private String local;@Value("3.14159")private Double price;@Overridepublic String toString() {return "Ginger{" +"local='" + local + '\'' +", price=" + price +'}';}public String getLocal() {return local;}public void setLocal(String local) {this.local = local;}public Double getPrice() {return price;}public void setPrice(Double price) {this.price = price;} }測(cè)試調(diào)用:
@SpringBootTest class ExtendsApplicationTests03 {@Autowiredprivate EventPublisher eventPublisher;@Testvoid contextLoads() {eventPublisher.publish("賣生姜啦,預(yù)防脫發(fā)很有效!");}}運(yùn)行結(jié)果:
test##### Ginger{local='China', price=3.14159}賣生姜啦,預(yù)防脫發(fā)很有效!ps:上面的監(jiān)聽使用了自己創(chuàng)建的SelfEvent event類型,如果使用ApplicationEvent,會(huì)把系統(tǒng)的事件也監(jiān)聽出來(lái)。
使用注解監(jiān)聽事件:@EventListener,可以添加多個(gè)class
但是監(jiān)聽方法只能有一個(gè)參數(shù)。
關(guān)于Spring *PostProcessor的總結(jié)
/** * bean的生命周期: * bean存在注冊(cè)信息(ImportBeanDefinitionRegistrar)-->被加載到beanfactory-->被創(chuàng)建實(shí)例 * -->屬性賦值(populate)-(BeanPostProcessor,*Aware)->初始化-->銷毀 * * beanfactory歷程: * spring首先創(chuàng)建beanfactory,然后標(biāo)準(zhǔn)初始化beanfactory。。 * 然后執(zhí)行BeanFactoryPostProcessor(包含兩個(gè)接口) * * BeanFactoryPostProcessor及其子接口 * BeanDefinitionRegistryPostProcessor * 根據(jù)實(shí)現(xiàn)PriorityOrder接口執(zhí)行子接口先。 * 再然后執(zhí)行“注冊(cè)BeanPostProcessor”。 * * ApplicationContextAware:屬性賦值之后,初始化之前 * BeanPostProcessor:在屬性賦值之后,初始化之前 * BeanNameAware:同上,可修改beanname; * BeanFactoryAware:在屬性賦值之后,初始化之前** BeanPostProcessor:Bean后置處理器,在bean對(duì)象初始化前后進(jìn)行攔截工作。* 1,BeanFactoryPostProcessor* 在beanfactory標(biāo)準(zhǔn)初始化之后調(diào)用:所有的bean的定義已經(jīng)加載到beanFactory但是還沒有被* 創(chuàng)建實(shí)例。可覆蓋屬性賦值。** 2,BeanDefinitionRegistryPostProcessor繼承了BeanFactoryPostProcessor* postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)* 在所以bean定義信息將要被加載,bean實(shí)例還未被創(chuàng)建的時(shí)候執(zhí)行。*/測(cè)試BeanDefinitionRegistryPostProcessor:
/*** registries that hold bean definitions** BeanDefinitionRegistry 為bean定義的存儲(chǔ)中心;以后BeanFactory就是* 按照BeanDefinitionRegistry里面保存的每一個(gè)bean定義信息創(chuàng)建bean實(shí)例。**/ @Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {System.out.println("postProcessBeanDefinitionRegistry...bean的數(shù)量:"+registry.getBeanDefinitionCount()+"!");RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Student.class);registry.registerBeanDefinition("mmp",rootBeanDefinition);AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Student.class).getBeanDefinition();registry.registerBeanDefinition("mmlgb",beanDefinition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的數(shù)量:"+beanFactory.getBeanDefinitionCount()+"!");} }測(cè)試BeanFactoryPostProcessor
一個(gè)函數(shù)式接口,使用lambda表達(dá)式。
測(cè)試ImportBeanDefinitionRegistrar,使用注解導(dǎo)入bean:@Import({MyImportBeanDefinitionRegistrar.class})
/*** AnnotationMetadata: 當(dāng)前類的注解信息* BeanDefinitionRegistry:* 注冊(cè)類把所有需要添加到容器中的bean* 調(diào)用registerBeanDefinitions手工注冊(cè)進(jìn)來(lái)*/ public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry){boolean mmb1 = registry.containsBeanDefinition("mmp");boolean mmb2 = registry.containsBeanDefinition("mmlgb");if(!mmb1 && !mmb2){registry.registerBeanDefinition("goodbye", new RootBeanDefinition(Student.class));System.out.println("注冊(cè)進(jìn)去goodbye");}} }測(cè)試BeanPostProcessor
@Component public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object o, String s) throws BeansException {if(o.getClass()==Lp.class){System.out.println("3+6= 9");}return o;}@Overridepublic Object postProcessAfterInitialization(Object o, String s) throws BeansException {if(s.equals("mmp")){System.out.println("-3-6= -9");}return o;} }幾種*Aware反注入的實(shí)現(xiàn)
運(yùn)行在bean實(shí)例化之后,初始化方法執(zhí)行之前: |
@Primary與@Scope 注解含義
@Configuration public class Cai {// @Scope("prototype")@Primary@Bean("mmp")public Lv lv1(){Lv lv = new Lv();lv.setAge(100);return lv;}}總結(jié)
以上是生活随笔為你收集整理的Spring注解驱动的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第五课:实现花样流水灯
- 下一篇: SpringBoot2尚硅谷笔记