Spring introduction and application - IOC

Spring is a lightweight IOC (inversion of control) / di (dependency injection) and AOP (aspect oriented programming) framework. The author of spring believes that

All objects used in business [create, initialize and destroy] should be managed by Spring, so as to simplify the development code;

1, IOC

The control is reversed, and the creation, initialization and destruction of objects are all managed by Spring; Through dynamic component registration, bean object initialization management, dependency injection

Implement the secondary business assembly before and after bean object initialization

1. Component configuration file

1)xml format

<?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 class = "com.test.bean.Test" id = "test">
    <property name ="id" value="1"></property>
    <property name ="name" value="10"></property>
</bean>

2) Annotation form

 @Configuration The modified class is equivalent to a configuration file

@Configuration//Equivalent to configuration file
public class ApplicationConfig {
//Indicates that the bean tag value in xml is the ID value. Here, multiple values can be separated by commas. Any value can represent this object
    @Bean(value={"t1","t2"})
	public Test test1(){
		return new Test();
	}
}

3) Acquisition method

AnnotationConfigApplicationContext context =
				  new AnnotationConfigApplicationContext(ApplicationConfig.class);
		  
		  System.out.println("Spring The container started...");
		  
		  Test t =(Test)context.getBean("t1");

2. Component registration

1) @ bean: identify a Java class to be managed by Spring, @ bean should be used in [configuration class]

  • By default, the keyword corresponding to the bean object decorated with @ bean is [method name]
  • If the key @ Bean(value={"a1","a2"}) corresponding to the bean object is specified in the @ bean, the keyword corresponding to the bean object in the Spring container is not [method name], but a1 or a2
  • All bean objects generated through @ bean decoration are singletons by default
  • For singleton bean objects, you can delay the creation time of variable objects by @ Lazy
    //This annotation is dedicated to the singleton mode bean object. At this time, the bean object will not be created when the spring container is started,
    //It is created only when a user visits
    @Lazy
    @Bean
    public Test test(){
    	return new Test();
    }
  • The bean listens for bean objects throughout its lifecycle

(1) You can specify methods for initialization and destruction

//bean class
public class Test {
	
	public void init(){
		System.out.println("The materialized object is initialized");
	}
	
	public void destory(){
		System.out.println("Materialized object destroyed");
	}
}




@Configuration//Equivalent to configuration file
public class ApplicationConfig {
    @Bean(initMethod="init",destroyMethod="destroy")
	public Test test(){
		return new Test();
	}
}

(2) let the bean class file implement InitializingBean interface and DisposableBean interface at the same time Listen to the instantiation time and destruction time of the bean of the current class according to the listening methods provided by the two interfaces

public class Test2 implements InitializingBean,DisposableBean{


	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Test2 Object destroyed");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Test2 Object initialization");
	}
}

(3) add these two annotations on the specified method in the class to specify the time @ predestroy & @ postconstruct when the listening bean object is instantiated and destroyed

public class Test3 {
	
	public Test3(){
		System.out.println("Constructor called");
	}
	
	@PostConstruct
	public void init(){
		System.out.println("Test3 Object is initialized");
	}
	@PreDestroy
	public void destroy(){
		System.out.println("Test3 Object destroyed");
	}
}

2) @ ComponentScan: automatically load the [class] under the specified package into the Spring container

     (@Controller,@Service,@Resposity,@Compoent);@ ComponentScan should be used in [configuration class]

Some classes can be excluded from the Spring container (excludeFilters attribute)

Some classes can be added to the Spring container (includeFilters attribute)

FilterType: scan filter policy

  • ANNOTATION is filtered according to annotations (@ controller, @ service, @ disposition, @ component)
  • ASSIGNABLE_TYPE specifies the type
  • ASPECTJ expression filtering
  • REGEX filters based on regular expressions
  • CUSTOM: filter rules are defined by the developer
@ComponentScan(value="com.test.beans",excludeFilters={
            		   @Filter(type=FilterType.ANNOTATION,
            				   value={Controller.class,Service.class}),
                       @Filter(type=FilterType.ASSIGNABLE_TYPE,
            		          value={Test01.class}
            		   
               })
//Scan com test. Classes under beans package, exclude classes annotated with @ Controller, and exclude class Test01 according to the specified type
@Configuration//Equivalent to configuration file
public class ApplicationConfig {

}


//


@ComponentScan(value="com.test.beans",useDefaultFilters=false,includeFilters={
            		   @Filter(type=FilterType.ANNOTATION,
            				   value={Controller.class,Service.class}),
                       @Filter(type=FilterType.ASSIGNABLE_TYPE,
            		          value={Test01.class}
            		   
               })
//Scan com test. Remove the default filtering rules from the classes under the beans package and scan@ Controller@Service Annotated class, scan class Test01 according to the specified type
@Configuration//Equivalent to configuration file
public class ApplicationConfig {

}

The custom scanning strategy is as follows

/**
**Custom scan policy
**Implements the TypeFilter interface Then override the match method in the TypeFilter interface
**/
public class CustomerFilter implements TypeFilter {

	public boolean match(MetadataReader arg0, MetadataReaderFactory arg1) throws IOException {
		//Gets the annotation type associated with the current bean
		AnnotationMetadata annotationMetadata = arg0.getAnnotationMetadata();
		String classname = annotationMetadata.getClassName();//Get class name
		//The full name of the annotation type modified on the current class
		Set<String> annotationTypes = annotationMetadata.getAnnotationTypes();
		System.out.println();
		for(String str:annotationTypes){
			System.out.println(str+"3543545");
		}
		//Gets the type information of the current bean class
		ClassMetadata classMetadata = arg0.getClassMetadata();
		String cn =classMetadata.getClassName();
		System.out.println("---"+cn);
		if(cn.contains("er")){
			System.out.println("Class meeting requirements"+cn);
			return true;
		}
		return false;
	}

}
@ComponentScan(value="com.test.beans",useDefaultFilters=false,
             includeFilters={
            		   @Filter(type=FilterType.CUSTOM,
            				   value={CustomerFilter.class})
            		   
               })
@Configuration//Equivalent to configuration file
public class ApplicationConfig2 {

}

3) @ Scope: identifies whether to create objects in single instance or multi instance mode. Use it in [configuration class], modify [method name], and the default single instance

@Scope("prototype"): identifies the object created by the multi instance mode

@Scope("singleton"): identifies the singleton pattern creation object

4) @ Conditional: determines whether the bean component will be registered in the SpringIoc container according to the specified conditions. It is used in the [configuration class] to modify the [method name]

An array is used in the conditional annotation. This array stores custom judgment conditions. Developers can define self judgment conditions by implementing the Condition interface

@ Conditional({custom condition type. class})

//Materialized objects under linux system
public class LinuxCondition implements Condition {

	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		
		  String systemName = context.getEnvironment().getProperty("os.name");
		  if(systemName.contains("Linux")){
			  return true;
		  }
		  return false;
	}

}



//Materialized object under windows system
public class WindowsCondition implements Condition {

	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		
		  String systemName = context.getEnvironment().getProperty("os.name");
		  if(systemName.contains("windows")){
			  return true;
		  }
		  return false;
	}

}

//Configuration class
@Configuration
public class ApplicationConfig {

	@Conditional({LinuxCondition.class})
	@Bean
	public Test test(){
		return new Test();
	}
}



//Test class
public class TestMain {

	public static void main(String[] args) {
		//1. Get the Spring container object
		  AnnotationConfigApplicationContext context =
				  new AnnotationConfigApplicationContext(ApplicationConfig.class);
		   //2. Get the bean object registered in the Spring container. You can find that the Test object running on windows is not materialized
		  String beanNames[]= context.getBeanDefinitionNames();
		  for(String beanName:beanNames){
			  System.out.println(beanName);
		  }

	}

}

5) @ import: specifies a way to import bean s into the SpringIOC container, which is the same type as @ ComponentScan

//Specify the Test class to join the Spring IOC
@Import(value="com.test.bean.Test.class")
@Configuration//Equivalent to configuration file
public class ApplicationConfig {

}

Or customize the selector by implementing ImportSelector

//Custom query
public class MyImport implements ImportSelector{

	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //Add two classes
		String array[] = {"com.test.beans.Test1","com.test.beans.Test2"};
		return array;
	}

}


//configuration file
@Import(MyImport.class)
@Configuration
public class ApplicationConfig {

}

6) FactoryBean is a method of registering beans provided by the Spring container. It is used to obtain the bean object of the component and the single instance or multi instance form of the bean object

//Implement FactoryBean interface
public class MyFactoryBean implements FactoryBean<Test1>{
	//Get instance object
	public Test1 getObject() throws Exception {
		// TODO Auto-generated method stub
		return new Test1();
	}
	
	//Get object type
	public Class<?> getObjectType() {
		// TODO Auto-generated method stub
		return Test1.class;
	}
	//This method does not override. The default is single column
	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return true;
	}
	
	

}
//Configuration class
@Configuration
public class ApplicationConfig {
	@Bean
	public MyFactoryBean getMyFactoryBean(){
		return new MyFactoryBean();
	}
}

3. Implementation of beanpostprocessor post processor

BeanPostProcessor is an interface, which is mainly used to perform some auxiliary functions before and after bean object initialization

Methods contained in the interface

Postprocessbeforeinitialization: work before the bean is initialized

postProcessAfterInitialization: work after initialization

//Define your own process
public class MyBeanPostProcess implements BeanPostProcessor{
	
	public MyBeanPostProcess(){
		System.out.println("Constructor called");
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("Before initialization"+beanName);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("After initialization"+beanName);
		return bean;
	}
	
	
}

//Add to the bean container
@Configuration//Equivalent to configuration file
public class ApplicationConfig3 {
    @Bean
	public MyBeanPostProcess myBeanPostProcess(){
		return new MyBeanPostProcess();
	}
}


//test
public class TestMain3 {

	public static void main(String[] args) {
		//1. Get the Spring container object
		  AnnotationConfigApplicationContext context =
				  new AnnotationConfigApplicationContext(ApplicationConfig3.class);
		  System.out.println("Spring The container started...");
		 //At this point, the container has started initializing the bean object, and the method in MyBeanPostProcess will be executed
	}

Keywords: Java Spring

Added by Tristan Wells on Wed, 05 Jan 2022 20:39:32 +0200