[黑马程序员SpringBoot2]——原理篇1

news2024/11/14 22:06:45

目录:

  1. bean的加载方式(—)
  2. bean的加载方式(二)
  3. bean的加载方式(三)
  4. FactoryBean
  5. proxyBeanMethod属性
  6. bean的加载方式(四)
  7. bean的加载方式(五)
  8. bean的加载方式(六)
  9. bean的加载方式(七)
  10. bean的加载方式(八)
  11. bean加载控制(编程式)
  12. bean加载控制(注解式)
  13. bean依赖属性配置

1.bean的加载方式(—)

XML方式声明bean

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima</groupId>
    <artifactId>springboot_27_bean_init</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.9</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>

    </dependencies>
</project>

 

App1.class

package cn.hdc.app;

import cn.hdc.bean.Dog;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App1 {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext1.xml");
//        Object cat = ctx.getBean("cat");
//        System.out.println(cat);
//
//        Dog dog = ctx.getBean(Dog.class);
//        System.out.println(dog);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

Cat.class

package cn.hdc.bean;

public class Cat {
}

 Dog.class

package cn.hdc.bean;

public class Dog {
}

Mouse.class

package cn.hdc.bean;

public class Mouse {
}

BookServiceImpl1.class

package cn.hdc.service.impl;

import cn.hdc.service.BookService;

public class BookServiceImpl1 implements BookService {
    @Override
    public void check() {
        System.out.println("book service 1...");
    }
}

BookServiceImpl2.class

package cn.hdc.service.impl;

import cn.hdc.service.BookService;

public class BookServiceImpl2 implements BookService {
    @Override
    public void check() {
        System.out.println("book service 2...");
    }
}

BookServiceImpl3.class

package cn.hdc.service.impl;

import cn.hdc.service.BookService;

public class BookServiceImpl3 implements BookService {
    @Override
    public void check() {
        System.out.println("book service 3...");
    }
}

BookServiceImpl4.class

package cn.hdc.service.impl;

import cn.hdc.service.BookService;

public class BookServiceImpl3 implements BookService {
    @Override
    public void check() {
        System.out.println("book service 3...");
    }
}

BookService.interface

package cn.hdc.service;

public interface BookService {
    void check();
}

 applicationContext1.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="cat" class="cn.hdc.bean.Cat"></bean>
    <bean class="cn.hdc.bean.Dog"></bean>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"></bean>
</beans>

applicationContext2.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

 2.bean的加载方式(二)

XML+注解方式声明bean

使用@Component及其衍生注解@Controller . @Service、@Repository定义bean

使用@Bean定义第三方bean,并将所在类定义为配置类或Bean

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
     ">

    <context:component-scan base-package="cn.hdc.bean,cn.hdc.config"/>
</beans>

 App2.class

package cn.hdc.app;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext2.xml");
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

Dbconfig.class

package cn.hdc.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class DbConfig {
    @Bean
    public DruidDataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        return ds;
    }
}

 

3.bean的加载方式(三)

注解方式声明配置类

 

App3.class

package cn.hdc.app;

import cn.hdc.config.SpringConfig3;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App3 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig3.class);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

SpringConfig3.class

package cn.hdc.config;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan({"cn.hdc.bean","cn,hdc.config"})
public class SpringConfig3 {
}

4.FactoryBean

注解方式声明配置类

@Configuration配置项如果不用于被扫描可以省略

初始化实现FactoryBean接口的类,实现对bean加载到容器之前的批处理操作 

 

App4.class

package cn.hdc.app;

import cn.hdc.config.SpringConfig4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App4 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig4.class);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        System.out.println(ctx.getBean("dog"));
        System.out.println(ctx.getBean("dog"));
        System.out.println(ctx.getBean("dog"));
    }
}

 DogFactoryBean.class

package cn.hdc.bean;

import org.springframework.beans.factory.FactoryBean;

public class DogFactoryBean implements FactoryBean<Dog> {

    @Override
    public Dog getObject() throws Exception {
        return new Dog();
    }

    @Override
    public Class<?> getObjectType() {
        return Dog.class;
    }

    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

 SpringConfig4.class

package cn.hdc.config;

import cn.hdc.bean.Dog;
import cn.hdc.bean.DogFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan({"cn.hdc.bean", "cn,hdc.config"})
public class SpringConfig4 {
//    @Bean
//    public Dog dog() {
//        return new Dog();
//    }

    @Bean
    public DogFactoryBean dog() {
        return new DogFactoryBean();
    }
}

5.proxyBeanMethod属性

 加载配置类并加载配置文件(系统迁移)

App32.class

package cn.hdc.app;

import cn.hdc.config.SpringConfig32;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App32 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig32.class);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

 SpringConfig32.class

package cn.hdc.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Component;

@ComponentScan({"cn.hdc.bean", "cn,hdc.config"})
@ImportResource("applicationContext1.xml")
@Component
public class SpringConfig32 {
}

applicationContext1.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="cat" class="cn.hdc.bean.Cat"></bean>
    <bean class="cn.hdc.bean.Dog"></bean>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"></bean>
    <bean class="com.alibaba.druid.pool.DruidDataSource"></bean>
    <bean class="com.alibaba.druid.pool.DruidDataSource"></bean>
</beans>

使用proxyBeanMethods=true可以保障调用此方法得到的对象是从容器中获取的而不是重新创建的

 

App33.class

package cn.hdc.app;

import cn.hdc.config.SpringConfig33;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App33 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig33.class);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        System.out.println("----------------------------");
        SpringConfig33 springConfig33 = ctx.getBean("springConfig33", SpringConfig33.class);
        System.out.println(springConfig33.cat());
        System.out.println(springConfig33.cat());
        System.out.println(springConfig33.cat());
    }
}

 SpringConfig33.class

package cn.hdc.config;

import cn.hdc.bean.Cat;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class SpringConfig33 {
    @Bean
    public Cat cat() {
        return new Cat();
    }
}

6.bean的加载方式(四)

使用@Import注解导入要注入的bean对应的字节码

被导入的bean无需使用注解声明为bean 

此形式可以有效的降低源代码与Spring技术的耦合度,在spring技术底层及诸多框架的整合中大量使用

使用@lmport注解导入配置类

 

App4.class

package cn.hdc.app;

import cn.hdc.bean.Dog;
import cn.hdc.config.SpringConfig4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App4 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig4.class);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        System.out.println("-----------------");
        System.out.println(ctx.getBean(Dog.class));
    }
}

SpringConfig4.class

package cn.hdc.config;

import cn.hdc.bean.Dog;
import org.springframework.context.annotation.Import;

@Import({Dog.class, DbConfig.class})
public class SpringConfig4 {

}

7.bean的加载方式(五)

使用上下文对象在容器初始化完毕后注入bean

 App5.class

package cn.hdc.app;

import cn.hdc.bean.Cat;
import cn.hdc.bean.Mouse;
import cn.hdc.config.SpringConfig5;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App5 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig5.class);
        ctx.registerBean("tom", Cat.class, 0);
        ctx.registerBean("tom", Cat.class, 1);
        ctx.registerBean("tom", Cat.class, 2);
        ctx.register(Mouse.class);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
        System.out.println(ctx.getBean(Cat.class));
    }
}

SpringConfig5.class

package cn.hdc.config;


public class SpringConfig5 {

}

Cat.class

package cn.hdc.bean;

import org.springframework.stereotype.Component;

@Component("tom")
public class Cat {
    int age;

    public Cat() {

    }


    public Cat(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "age=" + age +
                '}';
    }
}

Dog.class

package cn.hdc.bean;

import org.springframework.stereotype.Service;

//@Service("jerry")
public class Mouse {
}

8.bean的加载方式(六)

导入实现了ImportSelector接口的类,实现对导入源的编程式处理

 App6.class

package cn.hdc.app;

import cn.hdc.config.SpringConfig6;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App6 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig6.class);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

SpringConfig.class

package cn.hdc.config;


import cn.hdc.bean.MyImportSelector;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Import(MyImportSelector.class)
@Configuration
//@ComponentScan(basePackages = "cn.hdc")
public class SpringConfig6 {

}

MyImportSelector.class

package cn.hdc.bean;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

import java.util.Map;


public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
//        System.out.println("=======================");
//        System.out.println("提示:" + metadata.getClassName());
//        System.out.println(metadata.hasAnnotation("org.springframework.context.annotation.Configuration"));
//        Map<String, Object> attributes = metadata.getAnnotationAttributes("org.springframework.context.annotation.ComponentScan");
//        System.out.println(attributes);
//        System.out.println("=======================");

        boolean flag = metadata.hasAnnotation("org.springframework.context.annotation.Configuration");
        if (flag) {
            return new String[]{"cn.hdc.bean.Dog"};
        }
        return new String[]{"cn.hdc.bean.Cat"};
    }
}

9.bean的加载方式(七)

导入实现了ImportBeanDefinitionRegistrar接口的类,通过BeanDefinition的注册器注册实名bean,实现对容器中bean的裁定,例如对现有bean的覆盖,进而达成不修改源代码的情况下更换实现的效果

 App7.class

package cn.hdc.app;

import cn.hdc.config.SpringConfig7;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App7 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig7.class);
        String[] names = ctx.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

SpringConfig7.class

package cn.hdc.config;


import cn.hdc.bean.MyRegistar;
import org.springframework.context.annotation.Import;

@Import(MyRegistar.class)
public class SpringConfig7 {

}

MyRegistar.class

package cn.hdc.bean;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyRegistar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();

        registry.registerBeanDefinition("red", beanDefinition);
    }
}

10.bean的加载方式(八)

导入实现了BeanDefinitionRegistryPostProcessor接口的类,通过BeanDefinition的注册器注册实名bean,实现对容器中bean的最终裁定

App8.class

package cn.hdc.app;

import cn.hdc.bean.service.BookService;
import cn.hdc.config.SpringConfig8;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App8 {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig8.class);
        BookService bookService = ctx.getBean("bookService", BookService.class);
        bookService.check();
    }
}

SpringConfig8.class

package cn.hdc.config;


import cn.hdc.bean.MyPostProcessor;
import cn.hdc.bean.MyRegistar;
import cn.hdc.bean.MyRegistar2;
import cn.hdc.bean.service.impl.BookServiceImpl1;
import org.springframework.context.annotation.Import;

@Import({BookServiceImpl1.class, MyRegistar.class, MyRegistar2.class, MyPostProcessor.class})
public class SpringConfig8 {

}

MyRegistar.class

package cn.hdc.bean;

import cn.hdc.bean.service.BookService;
import cn.hdc.bean.service.impl.BookServiceImpl2;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyRegistar implements ImportBeanDefinitionRegistrar {

//    @Override
//    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
//        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
//
//        registry.registerBeanDefinition("red", beanDefinition);
//    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl2.class).getBeanDefinition();

        registry.registerBeanDefinition("bookService", beanDefinition);
    }
}

MyRegistar2.class

package cn.hdc.bean;

import cn.hdc.bean.service.impl.BookServiceImpl2;
import cn.hdc.bean.service.impl.BookServiceImpl3;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class MyRegistar2 implements ImportBeanDefinitionRegistrar {

//    @Override
//    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
//        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
//
//        registry.registerBeanDefinition("red", beanDefinition);
//    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl3.class).getBeanDefinition();

        registry.registerBeanDefinition("bookService", beanDefinition);
    }
}

MyPostProcessor.class

package cn.hdc.bean;

import cn.hdc.bean.service.impl.BookServiceImpl4;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl4.class).getBeanDefinition();

        registry.registerBeanDefinition("bookService", beanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

BookServiceImpl1.class

package cn.hdc.bean.service.impl;

import cn.hdc.bean.service.BookService;
import org.springframework.stereotype.Service;

@Service("bookService")
public class BookServiceImpl1 implements BookService {
    @Override
    public void check() {
        System.out.println("book service 1...");
    }
}

BookServiceImpl2.class 

package cn.hdc.bean.service.impl;

import cn.hdc.bean.service.BookService;

public class BookServiceImpl2 implements BookService {
    @Override
    public void check() {
        System.out.println("book service 2...");
    }
}

BookServiceImpl3.class  

package cn.hdc.bean.service.impl;

import cn.hdc.bean.service.BookService;

public class BookServiceImpl3 implements BookService {
    @Override
    public void check() {
        System.out.println("book service 3...");
    }
}

BookServiceImpl4.class  

package cn.hdc.bean.service.impl;

import cn.hdc.bean.service.BookService;

public class BookServiceImpl4 implements BookService {
    @Override
    public void check() {
        System.out.println("book service 4...");
    }
}

11.bean加载控制(编程式)

根据任意条件确认是否加载bean

Cat.class

package cn.hdc.bean;

import org.springframework.stereotype.Component;

@Component("tom")
public class Cat {
}

Dog.class

package cn.hdc.bean;

public class Dog {
}

Mouse.class

package cn.hdc.bean;

public class Mouse {
}

MyImportSelector.class

package cn.hdc.bean;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;


public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        try {
            Class<?> clazz = Class.forName("cn.hdc.bean.Mouse");
            if (clazz != null) {
                return new String[]{"cn.hdc.bean.Cat"};
            }
        } catch (ClassNotFoundException e) {
            return new String[0];
        }
        return null;
    }
}

SpringConfig.class

package cn.hdc.config;

import cn.hdc.bean.MyImportSelector;
import org.springframework.context.annotation.Import;

@Import(MyImportSelector.class)
public class SpringConfig {
}

App.class

package cn.hdc;

import cn.hdc.config.SpringConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        String[] beans = context.getBeanDefinitionNames();
        for (String bean : beans) {
            System.out.println(bean);
        }
    }
}

12.bean加载控制(注解式)

 

根据任意条件确认是否加载bean

 

使用@Conditional注解的派生注解设置各种组合条件控制bean的加载

匹配指定类

未匹配指定类

匹配指定类型的bean

 

匹配指定名称的bean

 

匹配指定环境

 

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>springboot_28_bean_load</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.5.4</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
        </dependency>
    </dependencies>

</project>

 Cat.class

package cn.hdc.bean;

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.stereotype.Component;

@Component("tom")
@ConditionalOnBean(name = "jerry")
//@ConditionalOnWebApplication
@ConditionalOnNotWebApplication
public class Cat {
}

Dog.class

package cn.hdc.bean;

public class Dog {
}

Mouse.class

package cn.hdc.bean;

import org.springframework.stereotype.Component;

@Component("jerry")
public class Mouse {
}

MyImportSelector.class

package cn.hdc.bean;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;


public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        try {
            Class<?> clazz = Class.forName("cn.hdc.bean.Mouse");
            if (clazz != null) {
                return new String[]{"cn.hdc.bean.Cat"};
            }
        } catch (ClassNotFoundException e) {
            return new String[0];
        }
        return null;
    }
}

SpringConfig.class

package cn.hdc.config;

import cn.hdc.bean.Cat;
import cn.hdc.bean.Dog;
import cn.hdc.bean.Mouse;
import cn.hdc.bean.MyImportSelector;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;

//@Import(MyImportSelector.class)
//@Import(Mouse.class)
@ComponentScan("cn.hdc.bean")
public class SpringConfig {
//    @Bean
    @ConditionalOnClass(name = "cn.hdc.bean.Mouse")
    @ConditionalOnMissingClass("cn.hdc.bean.Wolf")
//    @ConditionalOnBean(name = "jerry")
    @ConditionalOnMissingClass("cn.hdc.bean.Dog")
//    @ConditionalOnNotWebApplication
    @ConditionalOnWebApplication
//    public Cat tom() {
//        return new Cat();
//    }

    @Bean
    @ConditionalOnClass(name = "com.mysql.jdbc.Driver")
    public DruidDataSource dataSource() {
        return new DruidDataSource();
    }
}

13.bean依赖属性配置

将业务功能bean运行需要的资源抽取成独立的属性类(******Properties),设置读取配置文件信息

 

配置文件中使用固定格式为属性类注入数据

定义业务功能bean,通常使用@Import导入,解耦强制加载bean

使用@EnableConfigurationProperties注解设定使用属性类时加载bean

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_29_bean_properties</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_29_bean_properties</name>
    <description>springboot_29_bean_properties</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

CartoonCatAndMouse.class

package com.example.springboot_29_bean_properties.bean;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Data
@EnableConfigurationProperties(CartoonProperties.class)
public class CartoonCatAndMouse {

    private Cat cat;
    private Mouse mouse;

    private CartoonProperties cartoonProperties;

    public CartoonCatAndMouse(CartoonProperties cartoonProperties) {
        this.cartoonProperties = cartoonProperties;
        cat = new Cat();
        cat.setName(cartoonProperties.getCat() != null && StringUtils.hasText(cartoonProperties.getCat().getName()) ? cartoonProperties.getCat().getName() : "tom");
        cat.setAge(cartoonProperties.getCat() != null && cartoonProperties.getCat().getAge() != null ? cartoonProperties.getCat().getAge() : 3);
        mouse = new Mouse();
        mouse.setName(cartoonProperties.getMouse() != null && StringUtils.hasText(cartoonProperties.getCat().getName()) ? cartoonProperties.getMouse().getName() : "jerry");
        mouse.setAge(cartoonProperties.getMouse() != null && cartoonProperties.getMouse().getAge() != null ? cartoonProperties.getMouse().getAge() : 4);
    }

    public void play() {
        System.out.println(cat.getAge() + "岁的" + cat.getName() + "和" + mouse.getAge() + "岁的" + mouse.getName() + "打起来了");
    }
}

CartoonProperties.class

package com.example.springboot_29_bean_properties.bean;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "cartoon")
@Data
public class CartoonProperties {
    private Cat cat;
    private Mouse mouse;
}

Cat.class

package com.example.springboot_29_bean_properties.bean;

import lombok.Data;

@Data
public class Cat {
    private String name;
    private Integer age;
}

 Mouse.class

package com.example.springboot_29_bean_properties.bean;

import lombok.Data;

@Data
public class Mouse {
    private String name;
    private Integer age;
}

Springboot29BeanPropertiesApplicaiton.class

package com.example.springboot_29_bean_properties;

import com.example.springboot_29_bean_properties.bean.CartoonCatAndMouse;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Import(CartoonCatAndMouse.class)
public class Springboot29BeanPropertiesApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(Springboot29BeanPropertiesApplication.class, args);
        CartoonCatAndMouse bean = ctx.getBean(CartoonCatAndMouse.class);
        bean.play();
    }
}

小结:

  • 业务bean的属性可以为其设定默认值
  • 当需要设置时通过配置文件传递属性
  • 业务bean应尽量避免设置强制加载,而是根据需要导入后加载,降低spring容器管理bean的强度 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1248171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

加速 Selenium 测试执行最佳实践

Selenium测试自动化的主要目的是加快测试过程。在大多数情况下&#xff0c;使用 Selenium 的自动化测试比手动测试执行得特别好。在实际自动化测试实践中&#xff0c;我们有很多方式可以加速Selenium用例的执行。 我们可以选择使用不同类型的等待、不同类型的 Web 定位器、不同…

libmosquitto库的一个bug,任务消息id(mid)分配后不起作用

代码如图所示: 当订阅了所有主题后,每个主题的mid是他们的下标索引加100的数字,可是实际打印出来的值是: mid依然是1,2,这个参数在这里失效了,不知道是bug还是mqtt的什么机制?

2023 最新 PDF.js 在 Vue3 中的使用

因为自己写业务要定制各种 pdf 预览情况&#xff08;可能&#xff09;&#xff0c;所以采用了 pdf.js 而不是各种第三方封装库&#xff0c;主要还是为了更好的自由度。 一、PDF.js 介绍 官方地址 中文文档 PDF.js 是一个使用 HTML5 构建的便携式文档格式查看器。 pdf.js 是社区…

【Python进阶笔记】md文档笔记第6篇:Python进程和多线程使用(图文和代码)

本文从14大模块展示了python高级用的应用。分别有Linux命令&#xff0c;多任务编程、网络编程、Http协议和静态Web编程、htmlcss、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。 全套md格式笔记和代码自…

2015年全国硕士研究生入学统一考试管理类专业学位联考数学试题——解析版

文章目录 2015 级考研管理类联考数学真题一、问题求解&#xff08;本大题共 15 小题&#xff0c;每小题 3 分&#xff0c;共 45 分&#xff09;下列每题给出 5 个选项中&#xff0c;只有一个是符合要求的&#xff0c;请在答题卡上将所选择的字母涂黑。真题&#xff08;2015-01&…

白嫖CTG4.0

大家好&#xff0c;到点了我来给各位大佬献策CTG&#xff0c;不是花钱买不起&#xff0c;而是免费更有性价比&#xff0c;哈哈哈不调侃了我们自此开始正文&#xff0c;咱们主打的就是一个分享是一种态度 当然我更希望大家支持国产对国产有自己的信心&#xff08;文心一言&…

Ubuntu18.04安装A-Loam保姆级教程

系统环境&#xff1a;Ubuntu18.04.6 LTS 1.A-Loam的安装前要求&#xff1a; 1.1 ROS安装&#xff1a;参考我的另一篇博客 Ubuntu18.04安装ROS-melodic保姆级教程_灬杨三岁灬的博客-CSDN博客还是那句话&#xff0c;有时候加了这行也不好使&#xff0c;我是疯狂试了20次&#…

用XMind2TestCase,测试更轻松

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

(Java版)新一代最强开源UI自动化测试神器Playwright(模拟移动设备和浏览器行为)

使用 Playwright&#xff0c;你可以在任何浏览器上测试你的应用程序&#xff0c;也可以模拟真实设备&#xff0c;例如手机或平板电脑。只需配置你想要模拟的设备&#xff0c;Playwright 就会模拟浏览器行为&#xff0c;例如“userAgent”、“screenSize”、“viewport”以及是否…

PCB板材有哪些分类

1、按板材的刚柔程度分为刚性覆铜箔板和挠性覆铜箔板两大类。 2、按增强材料不同&#xff0c;分为&#xff1a;纸基、玻璃布基、复合基&#xff08;CEM系列等&#xff09;和特殊材料基&#xff08;陶瓷、金属基等&#xff09;四大类。 (一)纸基板 酚醛纸基板&#xff08;俗称…

一些在使用Python中常用网页字符串处理方法

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 首先一些Python字符串处理的简易常用的用法。 1.去掉重复空格 s "hello hello hello" s .join(s.split())2.去掉所有回车&#xff08;或其他字…

浅析linux中的信号

人们往往将信号称为“软件中断”&#xff0c;它提供了异步事件的处理机制&#xff0c;这些事件可以来自系统外部&#xff08;如用户按下ctrlc产生中断符&#xff09;&#xff0c;也可能来自程序或者内核内部的执行动作&#xff08;如进程除零操作&#xff09;。进程收到信号&am…

老生常谈 - 从输入URL到页面加载的过程(详细版)

从输入URL到页面加载的过程 之前一直都是直接看一下总结的八股文章&#xff0c;对于实际的整个链路并不是特别熟悉&#xff0c;这次花了一天多的时间看了很多资料&#xff0c;对于整个页面加载的流程有了自己的理解&#xff0c;从前端开始访问的浏览器多线程、缓存等问题&#…

在华为昇腾开发板安装gdal-python

作者:朱金灿 来源:clever101的专栏 为什么大多数人学不会人工智能编程?>>> 在华为昇腾开发板安装gdal-python分为两步:编译gdal库和下载gdal对应的python包。 1.编译gdal库 首先下载gdal库,。在linux(arm架构)上编译的gdal库及其第三方库源码,内含一个编译…

100%纯血鸿蒙来了,Android程序员影响甚大

“纯血鸿蒙”来了&#xff01; 近日&#xff0c;美团、网易、今日头条、钉钉等多家互联网头部企业密集发布对鸿蒙系统相关人才的招聘信息&#xff0c;再度引爆市场对“纯血鸿蒙”的热议。 操作系统之“国货之光” 自2019年8月发布至今&#xff0c;鸿蒙系统已经更新到4.0版本…

为医药数据建起坚不可摧的堡垒——上海迅软DSE终端防泄密的力量!

某医药公司是一家综合性的医药产业公司&#xff0c;具有一定的规模和实力。其经营范围大范围&#xff0c;涉及到多个领域&#xff0c;包括药品、医药器械等的批发零售以及相关的互联网信息服务等。该公司在人员配置和知识产权方面也具备一定的优势&#xff0c;为其在医药产业的…

实验题【网关设置+VRRP+静态路由+OSPF】(H3C模拟器)

嘿&#xff0c;这里是目录&#xff01; ⭐ H3C模拟器资源链接1. 实验示意图2. 要求和考核目标3. 当前配置3.1 PC1、PC2、PC3、PC4和PC5配置3.2 SW配置3.2.1 SW2配置3.2.2 SW3配置3.2.3 SW4配置3.2.4 SW1配置 3.2. R配置3.2.1 R1配置3.2.2 R2配置 ⭐ H3C模拟器资源链接 H3C网络…

SQL常见函数整理 _ LAG() 向上偏移

1. 用法 窗口函数&#xff0c;用于访问窗口中当前行之前的行的数据。该函数可以根据需要计算当前行之前的值&#xff0c;使我们能够轻松地比较不同行之间的差异和变化。 2. 基本语法 LAG(column, offset, default_value) OVER (ORDER BY column)column&#xff1a;代表在返回…

【Django笔记】10大模块md文档第6篇:Django视图、Cookie和session状态、模板和过滤器

Django的主要目的是简便、快速的开发数据库驱动的网站。它强调代码复用&#xff0c;多个组件可以很方便的以"插件"形式服务于整个框架&#xff0c;Django有许多功能强大的第三方插件&#xff0c;你甚至可以很方便的开发出自己的工具包。这使得Django具有很强的可扩展…

H5ke12--2--学生选课表格的编辑

方法1不可以修改的用label,如何按了哪一行 就会在下面有个文本显示可编辑的一行 方法2每一行后面都有一个编辑, 3对每一个修改,每一个td失去焦点都会有,直接到达我们服务器 注意 如果用span的每一个html元素都可以自己定义属性 Data-属性名,data-Address links也要给为span 1…