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 }