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

目录:

  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.mfbz.cn/a/187591.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前缀和+哈希表——560. 和为 K 的子数组

文章目录 &#x1fa90;1. 题目&#x1f31f;2. 算法原理⭐解法一&#xff1a;暴力枚举⭐解法二&#xff1a;前缀和哈希表 &#x1f31e;3. 代码实现 &#x1fa90;1. 题目 题目链接&#xff1a;560. 和为 K 的子数组 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组…

每日一题:LeetCode-102.二叉树的层序遍历

每日一题系列&#xff08;day 03&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

SAP smartform 实现打印条形码

先在SE73里定义一个新的BARCODE&#xff0c;注意一定要用新的才可以&#xff0c;旧的是打印不出来的。 然后定义一个SMARTFORM的样式&#xff0c;把你定义的BARCODE放到字符样式里面去。 再做SMARTFORM就可以了&#xff0c;将需要作为条码的变量的格式选为该BARCODE格式&…

是否有无限提取的代理IP?作为技术你需要知道这些

最近有互联网行业的技术小伙伴问到&#xff0c;有没有可以无限提取的代理IP&#xff1f;就是比如我一秒钟提取几万、几十万次&#xff0c;或者很多台机器同时调用API提取链接&#xff0c;这样可以吗&#xff1f;看到这个问题&#xff0c;不禁沉思起来&#xff0c;其实理论上是存…

cocos游戏引擎,弹出框浏览器正常,但到了抖音、微信小游戏就不显示的bug原因及解决办法

本篇文章主要讲解&#xff1a;cocos游戏引擎&#xff0c;浏览器测试时弹出框好好的&#xff0c;无任何报错&#xff0c;构建项目到抖音、微信小游戏时无法弹出弹出框&#xff0c;但又无报错的问题原因及解决办法。 日期&#xff1a;2023年11月25日 作者&#xff1a;任聪聪 问题…

linux系统中select函数的用法实现

前言&#xff1a; select机制已经被很多人都讲解过&#xff0c;select使用起来也不是特别难&#xff0c;为什么还要花时间再次讲解select机制&#xff1f; 在回答这个问题之前&#xff0c;我们先问一下自己&#xff0c;是否有足够的信心保证在使用select编程时不出错&#xf…

【数字图像处理】均值滤波与中值滤波

在数字图像处理中,均值滤波和中值滤波是常见的空间域处理方法,可以用于过滤图像中的噪声。本文主要介绍数字图像均值滤波与中值滤波的基本原理,并记录在紫光同创 PGL22G FPGA 平台的布署与实现过程。 目录 1. 均值滤波与中值滤波 2. FPGA 布署与实现 2.1 功能与指标定义

C语言 - 基础

C 语言 1. Hello World #include <stdio.h>int main(int argc, const char *argv[]) {printf("hello world\n");return 0; }注意: 所有的标点符号必须在英文状态下输入单词不要写错注意空格 创建 C语言 程序步骤&#xff1a; 1、创建一个文档&#xff0c;以…

MYSQL 及 SQL 注入

文章目录 前言什么是sql注入防止SQL注入Like语句中的注入后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;Mysql &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现…

「最优化基础知识2」一维搜索,以及python代码

最优化基础知识&#xff08;2&#xff09; 无约束优化问题&#xff0c;一维搜索 一、一维搜索 一维搜索的意思是在一个方向上找到最小点。 用数学语言描述&#xff0c;X*Xk tPk&#xff0c;从Xk沿着Pk方向行走t到达最小点X*。 1、收敛速度&#xff1a; 线性收敛&#xff1…

mac测试远程端口是否可连接

打开命令行工具&#xff0c;使用命令nc -z ip port即可 &#xff0c;如果成功&#xff0c;则会返回如下信息&#xff1a; 。

FANUC机器人系统配置相关--系统变量介绍

FANUC机器人系统配置相关–系统变量介绍 系统配置页相关变量 1- 停电处理$SEMIPOWERFL = TRUE(有效)/FALSE(无效) 2- 停电处理中的I/O $PWF_IO = 1(不恢复)/2(仿真恢复)/3(解除仿真)/4(恢复所有) 3- 停电处理无效时自动执行的程序 $PWR_NORMAL = ‘’ 4- 停电处理有效时自动…

【21年扬大真题】编写程序,通过指针p的改变,实现一维数组的输入及逆序输出

【21年扬大真题】编写程序&#xff0c;通过指针p的改变&#xff0c;实现一维数组的输入及逆序输出 例如&#xff0c;输入为1,2,3,4,5,6,7&#xff1b; 输出为7,6,5,4,3,2,1 法一&#xff1a;不改变原数组&#xff0c;仅逆序打印输出 #define _CRT_SECURE_NO_WARNINGS #includ…

Linux下安装python3步骤:

1.下载Python3源码 你需要从Python官网下载Python3的源码包。本文以Python 3.9.9为例。你可以使用wget命令来下载源码包到你的Linux主目录中: wget https://www.python.org/ftp/python/3.9.9/Python-3.9.9.tgz2.编译和安装Python3 下载好源码包后&#xff0c;你需要解压它&…

【外贸干货】领英客户开发与营销的六个策略方向

领英(LinkedIn)已经成为外贸营销人员&#xff0c;尤其是B2B外贸营销人员&#xff0c;一个重要且有效的社交媒体平台。 相比于其他社交媒体平台&#xff0c;领英(LinkedIn)在增加流量、产生高质量的潜在客户和建立思想领导力方面有着独有的优势。 因为领英(LinkedIn)不仅仅是获…

idea自动切换输入法Smart Input

idea搜索后下载 红色表示中文输入法 再ideavim场景下会自动切换成英文非常好用强烈推荐下载一个

英特尔和 ARM 将合作开发移动芯片技术,如何看待双方合作?

英特尔和 ARM 将合作开发移动芯片技术&#xff0c;如何看待双方合作&#xff1f; 最近市场传出Arm要自产芯片&#xff0c;供智能手机与笔电等使用后&#xff0c;外媒指Arm自产芯片将由英特尔晶圆代工部门打造&#xff0c;变成英特尔晶圆代工客户。将采用英特尔18A工艺&#xff…

电子学会C/C++编程等级考试2022年03月(二级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:温度统计 现有一段时间的温度数据,请统计指定温度出现的次数。 时间限制:1000 内存限制:65536输入 第一行一个整数n,表示温度数据的个数。(0 < n ≤ 200) 第二行n个整数,以空格分隔,每个整数表示一个温度,温度的范围大…

我好像发现了车载测试面试成功的秘籍

在汽车行业中&#xff0c;车载测试工程师扮演着至关重要的角色。他们负责确保汽车的各种系统和功能在各种条件下都能正常运行&#xff0c;以确保车辆的安全性、可靠性和性能。如果你梦想成为一名车载测试工程师&#xff0c;那么你可能需要准备好回答一些关键的面试问题。在本文…

华大基因基因检测产品发布,助力早发冠心病风险评估

冠状动脉性心脏病&#xff0c;简称冠心病。冠心病作为导致猝死的常见原因之一&#xff0c;近年来备受关注。早发冠心病是指冠心病发病年龄男性≤55岁&#xff0c;女性≤60岁。早发冠心病是一种发病时心肌损伤严重的冠心病&#xff0c;由于心肌缺血&#xff0c;还有可能会导致急…