目 录
序言
本文主要的简单的介绍了SpringIOC依赖注入的多种方法的其中需要的一些细节
@SpringBootApplication
放置在Springboot启动类上,表明该类是开启Springboot容器的入口,它是一个复合注解。里面包含了包扫描,自动注入,配置注入的功能
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
bean.xml最原始的bean配置文件注入
创建要注入的bean类
package com.example.demo.bean;
/**
* @author 邓琦
* @version 1.0
* @description: TODO
* @date 2021/9/7 10:49
*/
public class person {
private int age;
private String name;
@Override
public String toString() {
return "person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public person() {
}
public person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建beans.xml文件 并注入person类
<?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="person" class="com.example.demo.bean.person" >
<property name="age" value="18"></property>
<property name="name" value="小明"></property>
</bean>
</beans>
test测试
package com.example.demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 邓琦
* @version 1.0
* @description: TODO
* @date 2021/9/7 10:52
*/
public class test {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml");
Object person = classPathXmlApplicationContext.getBean("person");
System.out.println(person);
}
}
运行:
@Configuration配置类注入
创建配置类
package com.example.demo.config;
import com.example.demo.bean.person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author 邓琦
* @version 1.0
* @description: 配置类 注册bean
* @date 2021/9/7 11:03
*/
@Configuration
public class MainConfig {
@Bean("person1")
public person person(){
return new person("小红",20);
}
}
测试
package com.example.demo;
import com.example.demo.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
/**
* @author 邓琦
* @version 1.0
* @description: TODO
* @date 2021/9/7 10:52
*/
public class test {
public static void main(String[] args) {
//配置类注解
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Object person = annotationConfigApplicationContext.getBean("person1");
System.out.println(person);
String[] beanNamesForType = annotationConfigApplicationContext.getBeanNamesForType(person.getClass());
for (String name : beanNamesForType) {
System.out.println(name);
}
}
}
运行:
@ComponentScan包扫描注入bean
概念:只要标注了@Service @Controller @Repository @Component 设置了包扫描的路径,就会添加到IOC容器中
可以添加包扫描过滤:excludeFilters排除包含,includeFilters只包含
package com.example.demo.config;
import com.example.demo.Controller.TestController;
import com.example.demo.bean.person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
/**
* @author 邓琦
* @version 1.0
* @description: 配置类 注册bean
* @date 2021/9/7 11:03
*/
@Configuration
//过滤规则 FilterType
// 1.ANNOTATION(注解过滤) 2.ASSIGNABLE_TYPE 3.ASPECTJ 4.CUSTOM 5.REGEX
@ComponentScan(value = "com.example.demo",excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})})
public class MainConfig {
@Bean("person1")
public person person(){
return new person("小红",20);
}
}
测试
@SuppressWarnings("resource")
@Test
public void test04(){
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
@ComponentScan包扫描自定义过滤规则
自定义过滤类
package com.example.demo.MyFilter;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import java.io.IOException;
/**
* @author 邓琦
* @version 1.0
* @description: TODO
* @date 2021/9/7 21:52
*/
public class MyTypeFilter implements TypeFilter {
/*
自定义过滤规则
metadataReader: 读取当前正在扫描的类的信息
metadataReaderFactory:可以获取到其他任何类信息
*/
@Override
public 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);
//过滤规则
if(className.contains("er")){
return true;
}
return false;
}
}
测试
@SuppressWarnings("resource")
@Test
public void test04(){
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
@Lazy
懒加载:单实例bean ,默认容器启动时候创建对象,容器启动不创建对象,第一次使用(获取)bean创建对象,并初始化
@Conditional 按照条件注册bean
继承Condition类,书写条件
package com.example.demo.Conditional;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* @author 邓琦
* @version 1.0
* @description: TODO
* @date 2021/9/8 11:39
*/
//按照条件判断注册bean
public class ConditionalTest implements Condition {
//conditionContext 判断条件能使用的上下文(环境)
//annotatedTypeMetadata:注释信息
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//能获取到ioc使用到的 beanFactory
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获取当前环境
Environment environment = conditionContext.getEnvironment();
//获取到bean定于的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
//获取当前是否的系统环境
String property = environment.getProperty("os.name");
if (property.contains("Windows 10")) {
return true;
}
return false;
}
}
使用可以在方法上使用也可以在类上中使用
@Conditional({ConditionalTest.class})
@improt 全名导入bean
@Import({color.class})
@improt 使用importSelector
package com.example.demo.ImportSelector;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* @author 邓琦
* @version 1.0
* @description: TODO
* @date 2021/9/8 12:41
*/
public class MyImportSelector implements ImportSelector {
//返回值:就是导入到容器中的组件的全类名
//AnnotationMetadata 当前标注@ Import注解类的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.example.demo.bean.blue","com.example.demo.bean.green"};
}
}
@improt 使用ImportBeanDefinitionRegistrar 手动注册
package com.example.demo.importBeanDfinitionReg;
import com.example.demo.bean.ranBOW;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
/**
* @author 邓琦
* @version 1.0
* @description: TODO
* @date 2021/9/8 12:51
*/
public class importBeanDfinition implements ImportBeanDefinitionRegistrar{
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean blue = registry.containsBeanDefinition("com.example.demo.bean.blue");
if (blue){
//指定bean的类型和scope
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(ranBOW.class);
registry.registerBeanDefinition("ranBOW",rootBeanDefinition);
}
}
}
实现FactoryBean注册组件
package com.example.demo.beanfactory;
import com.example.demo.bean.color;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
/**
* @author 邓琦
* @version 1.0
* @description: TODO
* @date 2021/9/8 13:03
*/
public class Colorbeanfactory implements FactoryBean<color> {
@Override
public color getObject() throws Exception {
System.out.println("getobject ++++++=");
return new color();
}
@Override
public Class<?> getObjectType() {
return color.class;
}
//控制是否时单例 true为单例 false为多实例
@Override
public boolean isSingleton() {
return true;
}
}
配置类注册 ,看着是注册的 Colorbeanfactory 实际上是 color
//添加工厂bean
@Bean
public Colorbeanfactory Colorbeanfactory(){
return new Colorbeanfactory();
}
测试
@Test
public void test06(){
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
//遍历注册的bean
for (String name : beanDefinitionNames) {
System.out.println(name);
}
Object colorbeanfactory = annotationConfigApplicationContext.getBean("Colorbeanfactory");
Class<?> aClass = colorbeanfactory.getClass();
System.out.println("Colorbeanfactory的类型"+aClass);
Object colorbeanfactory1 = annotationConfigApplicationContext.getBean("&Colorbeanfactory");
Class<?> aClass1 = colorbeanfactory1.getClass();
System.out.println("&Colorbeanfactory的类型"+aClass1);
}
如果没有批评,赞美将毫无意义,欢迎指正批评。
路漫漫其修远兮,吾将上下而求索