日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring注解驱动之注册组件(spring的再回顾)

發布時間:2024/3/7 javascript 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring注解驱动之注册组件(spring的再回顾) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一. 組件注冊

1. 給容器中注冊組件

xml方式

  • 創建一個實體類(構造方法等省略)

    public class Person {private String name;private Integer age;}
  • resources資源目錄下創建xml文件

    • 利用bean標簽注冊一個組件
    • 得到id,方便從容器中獲取該bean
    • 使用property進行屬性賦值
    <bean id="person" class="com.lcy.bean.Person"><property name="name" value="諸葛亮"/><property name="age" value="18"/> </bean>
  • 創建一個測試類

    • 傳入配置文件的位置,返回IOC容器
    • 根據id獲取值
    @Testpublic void t1() {// new一個CPXAC傳入配置文件的位置,返回IOC容器applicationContextApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");// 根據id獲取組件Person person = (Person) applicationContext.getBean("person");System.out.println(person);}
  • 控制臺輸出

    Person{name='諸葛亮', age=18}

配置類方式

  • 實體類不變

  • 創建一個配置類

    // 配置類==配置文件 @Configuration // 告訴Spring這是一個配置類 public class MainConfig {// 給容器注冊一個Bean,類型為返回值的類型,id默認是方法名(可以直接指定value方法值)@Beanpublic Person person() {return new Person("劉備",19);}}
  • 測試類(入口代碼省略)

    @Testpublic void t2() {// new一個AnnotationConfigApplicationContext,傳入配置文件,得到IOC容器ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);// 根據類型獲取值Person bean = applicationContext.getBean(Person.class);System.out.println("根據類型獲取"+bean);// 根據Id獲取,默認Id就是方法名String[] namesForType = applicationContext.getBeanNamesForType(Person.class);for (String name : namesForType) {System.out.println("獲取該組件的id是"+name);}}
  • 控制臺

    根據類型獲取Person{name='劉備', age=19} 獲取該組件的id是person

2. 自動掃描組件與指定掃描規則

xml文件掃描時

  • 在配置文件中配置

    • 只要指定包下的標注了Controller,Service,Repository,Component就會被掃描到
    <context:component-scan base-package="com.lcy"/>

配置文件包掃描

  • 在配置類上加上注解@ComponentScan

    // 配置類==配置文件 @ComponentScan(value = "com.lcy") // 包掃描 @Configuration // 告訴Spring這是一個配置類 public class MainConfig {@Beanpublic Person person() {return new Person("劉備",19);} }
  • 測試

    • 獲取當前IOC中所有組件的名字
    @Test public void t3() {ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig.class);// 獲取容器中所有組件的名字String[] names = ioc.getBeanDefinitionNames();for (String name : names) {System.out.println(name);} }
  • 控制臺

    org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig personController personDao personService person
  • excludeFilters(排除)

  • 排除Controller和Service標注的組件

```Java @ComponentScan(value = "com.lcy",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})}) @Configuration public class MainConfig {@Beanpublic Person person() {return new Person("劉備",19);}} ```
  • 控制臺

    • 與上次輸出比較,過濾規則起作用了
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig personDao person
  • includeFilters(只包含)

    • 恰恰相反,需要禁用掉默認過濾規則才能生效

      • useDefaultFilters = false
    • 只要Controller和Service標注的組件

    @ComponentScan(value = "com.lcy",includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})},useDefaultFilters = false) @Configuration public class MainConfig {@Beanpublic Person person() {return new Person("劉備",19);} }
    • 控制臺

      org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig personController personService person

掃描規則

@ComponentScan(value = "com.lcy",includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class}),@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = PersonDao.class)},useDefaultFilters = false) // @ComponentScan value:指定要掃描的包 // includeFilters = Filter[]:指定掃描時只需要包含哪些組件 // excludeFilters = Filter[]:指定掃描時按照規則排除組件 // FilterType.ANNOTATION:按照注解(常用) // FilterType.ASSIGNABLE_TYPE:按照類型(常用)所有的其子類實現類都會被加載進來 // FilterType.ASPECTJ:按照ASPECTJ表達式 // FilterType.REGEX:按照正ava則 // FilterType.CUSTOM:按照自定義規則(需要TypeFilter的實現類)
  • 自定義過濾規則

    • 創建一個類實現TypeFilter接口

      public class MyTypeFilter implements TypeFilter {/**** @param metadataReader 讀取到的當前正在掃描類的信息* @param metadataReaderFactory 可以讀取到其他任何類的信息* @return* @throws IOException*/@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {// 獲取當前類注解的信息AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();// 獲取當前正在掃描類的類信息(比如實現了什么接口,什么類型)ClassMetadata classMetadata = metadataReader.getClassMetadata();// 獲取當前類資源(類的路徑)Resource resource = metadataReader.getResource();// 獲取當前正在處理類的類名String className = classMetadata.getClassName();System.out.println("----->類名"+className);// 如果類名中包含Dao,則返回true,匹配成功放行if (className.contains("Dao")) {return true;}return false;}}
    • 配置類進行設置

      @Configuration @ComponentScan(value = "com.lcy",includeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM,classes = MyTypeFilter.class)}, // 自定義規則useDefaultFilters = false) public class MainConfig {@Beanpublic Person person() {javareturn new Person("劉備",19);} }
    • 控制臺

      ----->類名com.lcy.bean.Person ----->類名com.lcy.config.MyTypeFilter ----->類名com.lcy.controller.PersonController ----->類名com.lcy.dao.PersonDao ----->類名com.lcy.service.PersonService org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig personDao personProcess finished with exit code 0

3. @Scope設置作用域

默認單例

  • 配置類

    @Configuration public class MainConfig2 {// 默認為單例/*** prototype:多實例的* singleton:單實例的(默認值)ioc容器每次調用方法創建對象放到ioc容器中* 之后的每一次獲取都是直接從容器中拿* request: 同一次請求創建一個實例(需要web環境)* session: 同一個Session創建一個實例(需要web環境)*/@Scope@Beanpublic Person person() {System.out.println("給容器添加Person");return new Person("周瑜",20);}}
  • 測試類

    @Test public void t4() {ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig2.class);// 根據Id來獲取Person bean1 = (Person) ioc.getBean("person");Person bean2 = (Person) ioc.getBean("person");// 默認單例,判斷兩個對象是否相等System.out.println(bean1 == bean2); // true}
  • 控制臺

    給容器添加Person IOC容器創建完成 true

多例

  • 配置類

    @Configuration public class MainConfig2 {@Bean/*** prototype:多實例的:ioc啟動并不會創建對象放在容器* 每次獲取時才會調用方法創建對象*/@Scope("prototype")public Person person() {System.out.println("給容器添加Person");return new Person("周瑜",20);} }
  • 測試類

    @Testpublic void t4() {ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig2.class);System.out.println("IOC容器創建完成");// 根據Id來獲取Person bean1 = (Person) ioc.getBean("person");Person bean2 = (Person) ioc.getBean("person");// 修改為prototype,判斷兩個對象是否相等System.out.println(bean1 == bean2); // false}
  • 控制臺

    IOC容器創建完成 給容器添加Person 給容器添加Person false

懶加載

  • 配置類(未啟動懶加載)

    @Configuration public class MainConfig2 {// 默認為單例@Bean/*** singleton:單實例的(默認值)ioc容器每次調用方法創建對象放到 ioc容器中* 懶加載:* 單實例Bean:默認在容器啟動時創建對象* 懶加載:容器啟動時不創建對象,第一次(使用)獲取Bean創建 對象并初始化**/@Scopepublic Person person() {System.out.println("給容器添加Person");return new Person("周瑜",20);} }
  • 測試類

    @Testpublic void t4() {ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig2.class);System.out.println("IOC容器創建完成");}
  • 控制臺

    • 在IOC啟動的時候就創建完成了
    給容器添加Person IOC容器創建完成
  • 啟用懶加載@Lazy

    • 配置類

      @Configuration public class MainConfig2 {@Bean@Scope@Lazypublic Person person() {System.out.println("給容器添加Person");return new Person("周瑜",20);} }
    • 測試類與控制臺(未使用Bean)

      @Testpublic void t4() {ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig2.class);System.out.println("IOC容器創建完成");} IOC容器創建完成
    • 測試類與控制臺(使用Bean)

      • 使用Bean時才會創建,并且只會創建一次
      @Testpublic void t4() {ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig2.class);System.out.println("IOC容器創建完成");// 根據Id來獲取Person bean1 = (Person) ioc.getBean("person");Person bean2 = (Person) ioc.getBean("person");} IOC容器創建完成 給容器添加Person

4. @Conditional按照條件注冊bean

  • 若放在類上,必須滿足條件,此類中的bean注冊才能生效

  • 條件:

    • 如果是windows,給容器中注冊windows
    • 如果是Linux,給容器中注冊Linux
  • 配置類

    /*** @return* @Conditional({}) :按照一定條件進行判斷,滿足條件給容器中注冊 bean*/ @Conditional({WindowsCondition.class}) // 放在類上,必須滿足條件,此類中的bean注冊才能生效 @Bean("Windows") public Person person1() {return new Person("Windows", 22); }@Bean("Linux") @Conditional({LinuxCondition.class}) public Person person2() {return new Person("Linux", 20); }
  • 分別創建兩個類實現Condition接口

    // 判斷是否為Linux系統 public class LinuxCondition implements Condition {@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {Environment environment = conditionContext.getEnvironment();String property = environment.getProperty("os.name");if (property.contains("Linux")) {return true;}return false;}java } // 判斷是否為Windows系統 public class WindowsCondition implements Condition {/**** @param conditionContext 判斷條件能使用的上下文環境* @param annotatedTypeMetadata 注釋信息* @return*/@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {// 1.能獲取到IOC使用的beanfactoryConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();// 2.獲取類加載器ClassLoader classLoader = conditionContext.getClassLoader();// 3.獲取當前環境信息Environment environment = conditionContext.getEnvironment();// 4.獲取到bean定義的注冊類BeanDefinitionRegistry registry = conditionContext.getRegistry();// 可以判斷容器中的bean注冊情況,也可以給容器中注冊beanboolean person = registry.containsBeanDefinition("person");// 獲取操作系統String property = environment.getProperty("os.name");// 判斷是否為Windows系統if (property.contains("Windows")){return true;}return false;} }
  • 測試類

    @Test public void t5() {ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig2.class);String[] beanNamesForType = ioc.getBeanNamesForType(Person.class);for (String name : beanNamesForType) {System.out.println(name);}Map<String, Person> personMap = ioc.getBeansOfType(Person.class);System.out.println(personMap);}
  • 控制臺

    • 因為是Windows操作系統,所以Linux并沒有注冊進來
    • person是之前已注冊的
    person Windows 給容器添加Person {person=Person{name='周瑜', age=20}, Windows=Person{name='Windows', age=22}}

5. @Import導入組件

@Import

  • 創建一個實體類

    public class Color {}
  • 配置類加入類名@Import

    @Configuration @Import(Color.class) //@Import({Color.class, Person.class}) 也可以導多個類 public class MainConfig3 {/*** 給容器中注冊組件:* 1.包掃描+組件標注注解(@Controller,@Service,@Repository,@Component)[局限于自己創建的類]* 2.@Bean[導入的第三方包里面的組件]* 3.@Import[快速給容器中導入一個組件]* 1.@Improt(要導入容器的組件),容器會自動注冊這個組件,id默認是全類名*/}
  • 測試類

    @Test public void t6() {ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig3.class);String[] names = ioc.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
  • 控制臺

    org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig3 com.lcy.bean.Color

ImportSelector接口

  • 創建一個類實現ImportSelector接口

    // 自定義邏輯返回需要導入的組件 public class MyImportSelector implements ImportSelector {/*** 返回值就是要導入到容器中的組件全類名* @param annotationMetadata :當前標注@Import注解類的所有注解信息* @return*/@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {// 放入需要注冊組件的全類名return new String[]{"com.lcy.bean.Red","com.lcy.bean.Blue"};} }
  • 配置類

    @Configuration @Import({Color.class, MyImportSelector.class}) public class MainConfig3 {/*** ImportSelector:返回需要導入的組件的全類名數組* 創建一個類實現ImportSelector接口,在@Import上導入*/}
  • 測試(代碼如上不變)控制臺

    org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig3 com.lcy.bean.Color com.lcy.bean.Red com.lcy.bean.Blue

ImportBeanDefinitionRegistrar接口

  • 創建新的實體類

    public class RainBow { }
  • 配置類

    @Configuration @Import({Color.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class}) public class MainConfig3 {/*** ImportBeanDefinitionRegistrar:手動注冊bean到容器*/}
  • 創建一個類實現ImportBeanDefinitionRegistrar接口

    public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/**** @param importingClassMetadata:當前類的注解信息* @param registry : 把所有需要添加到容器中的bean,* 調用registry.registerBeanDefinition手工注冊進來*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {// 指定bean的定義信息(Bean的類型)RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);// 注冊一個bean,指定bean名registry.registerBeanDefinition("rainBow",beanDefinition);} }
  • 測試類(代碼不變)與控制臺

    org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfig3 com.lcy.bean.Color com.lcy.bean.Red com.lcy.bean.Blue rainBow

FactoryBean工廠Bean

  • 配置類

    /*** .使用Spring提供的FactoryBean(工廠Bean)* 1.默認獲取到的是工廠Bean調用getObject創建的對象* 2.要獲取工廠Bean本身,則在id前加一個&*/ @Bean // 雖然注冊的是YellowFactoryBean,但實際上是Yellow public YellowFactoryBean yellowFactoryBean() {return new YellowFactoryBean(); }
  • 創建一個實體類

    public class Yellow { }
  • 創建一個類實現FactoryBean接口

    public class YellowFactoryBean implements FactoryBean<Yellow> {// 返回一個Yellow對象,這個對象會添加到容器中@Overridepublic Yellow getObject() throws Exception {System.out.println("YellowFactoryBean。。。。。getObject");return new Yellow();}// 返回對象的類型@Overridepublic Class<?> getObjectType() {return Yellow.class;}// 控制是否單例:true為單例; 在容器中保存一份// false:多例;每次獲取都會創建一個新的bean,獲取的時候會調用getObject@Overridepublic boolean isSingleton() {return true;} }
  • 測試類

    @Test public void t6() {ApplicationContext ioc = new AnnotationConfigApplicationContext(MainConfig3.class);// 工廠Bean獲取的是調用gerObject創建的對象Object bean = ioc.getBean("yellowFactoryBean");System.out.println("bean的類型="+bean.getClass());// 若想獲取工廠Bean的本身則加&Object bean1 = ioc.getBean("&yellowFactoryBean");System.out.println("bean的類型="+bean1);}
  • 控制臺

    YellowFactoryBean。。。。。getObject bean的類型=class com.lcy.bean.Yellow bean的類型=com.lcy.condition.YellowFactoryBean@1f0f1111

總結

以上是生活随笔為你收集整理的Spring注解驱动之注册组件(spring的再回顾)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。