Deep spring explain in detail the actual use --spring source article

First of all, this article will not be detailed further underlying source code, just say our spring annotations and configuration is based, do not underestimate the foundation to ensure that you have not used annotations and configuration, go play.

We first establish a maven project, the introduction of spring file, do not love to get in the bottom there is article code address can go to download. Look, behind their own download code yourself to try. You give it, while trying to watching it.

1. Basic XML injection Bean

<?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="car" class="com.springIOC.bean.CarBean"></bean>
</beans>
package com.springIOC;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext cac = new ClassPathXmlApplicationContext("config.xml");
        Object car = cac.getBean("car");
    }
}

It is not super simple, a little bit to our progressive approach.

2. annotation-based approach to configuration

package com.springIOC2.config;

import com.springIOC.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {
    @Bean
        public CarBean car(){
        
        return new CarBean();
    }
}
package com.springIOC2;

import com.springIOC2.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        Object car = aca.getBean("car");
    }
}

We can directly get our object through the method name, the default method is in accordance to the assembly. Can also @Bean (value = "newName") to specify the name of the assembly.

It is September and October quit quarter, as we collected a 2019 interview date information, there are documents, there are the Raiders, there is video. Needy students can confidant] [Java, sending No. More interviews in public to receive information on the latest interview Raiders! Cypher [1024] do not send, or else .....

3. The package assembly of scanned manner (focus) using @ComponentScan (basePackages = { "bag full path"})

package com.springIOC3.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = {"com.springIOC3"})
public class MainConfig {
}
package com.springIOC3;

import com.springIOC3.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanDefinitionNames = aca.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("beanDefinitionName = " + beanDefinitionName);
        }
    }
}

Here in terms of several parameters, excludeFilters exclude a number of objects, syntax is as follows

excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class}),  
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {RepositoryBean.class}) 
}

FilterType There are five kinds of ANNOTATION (class notes), ASSIGNABLE_TYPE (class name), ASPECTJ (not commonly used, the document said AspectJ type pattern expression matching), REGEX (regular expression matching), CUSTOM (custom), common I marked three kinds of red. Let's look at the specific wording

package com.springIOC3b.config;

import com.springIOC3b.repository.RepositoryBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

@Configuration
@ComponentScan(basePackages = {"com.springIOC3b"},excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class}),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {RepositoryBean.class})
}
)

public class MainConfig {
}

Just now we talked a custom filter, we look at how to write self-defined filtering, to achieve our TypeFilter interface can rewrite our match, only concerned with the return of true. Here is a case

package com.springIOC3c.config;

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;

public class CustomFilterType implements TypeFilter {
    @Override
        public Boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        
        Resource resource = metadataReader.getResource();
        if (classMetadata.getClassName().contains("RepositoryBean")) {
            
            return true;
        }
        
        
        
        return false;
    }
}

There is also a contrary contained only allow the introduction of what is our includeFilters, need to pay attention to the need to useDefaultFilters property is set to false (true representation of the entire scanning). Exactly the same syntax and excludeFilters

package com.springIOC3d.config;

import com.springIOC3d.service.ServiceBean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;

@Configuration
@ComponentScan(basePackages = {"com.springIOC3d"},includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class}),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = ServiceBean.class)
}
,useDefaultFilters = false)

public class MainConfig {
}

4. Looking back, we look at the Bean scopes.

@Lazy lazy loading, use only instantiated, look at the code, we join in Constructor Bean, the more easily obtained when instantiated.

package com.springIOC4.config;

import com.springIOC4.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@Configuration
public class MainConfig {
    @Bean
        @Lazy
        public CarBean car(){
        return new CarBean();
    }
}

There are four scopes can be specified @Scpoe

a) singleton single instance (the default), the life cycle of a single embodiment of the vessel to have a spring in the spring after the non-lazy loading instantiation object is generated, destruction of the container object is destroyed

package com.springIOC4b.config;

import com.springIOC4b.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

@Configuration
public class MainConfig {
    @Bean
        @Scope(value = "singleton")
        public CarBean car(){
        return new CarBean();
    }
}
package com.springIOC4b;

import com.springIOC4b.bean.CarBean;
import com.springIOC4b.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        CarBean car = (CarBean)aca.getBean("car");
        CarBean car2 = (CarBean)aca.getBean("car");
        System.out.println(car == car2);
        
    }
}

The output is true, that we are singleton object, the object singleton, life cycle managed by the spring.

b) prototype multi-instance

package com.springIOC4c.config;

import com.springIOC4c.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class MainConfig {
    @Bean
        @Scope(value = "prototype")
        public CarBean car(){
        return new CarBean();
    }
}
package com.springIOC4c;

import com.springIOC4c.bean.CarBean;
import com.springIOC4c.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        CarBean car = (CarBean)aca.getBean("car");
        CarBean car2 = (CarBean)aca.getBean("car");
        System.out.println(car == car2);
        
    }
}

Ioc container not to manage multiple cases, when destroyed by the GC to clean up, as well as request with a request and a session with session-level, here is not demonstrated.

5. @ Configuration annotation, to determine whether injection of Bean.

package com.springIOC5.config;

import com.springIOC5.bean.CarBean;
import com.springIOC5.bean.UserBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {
    @Bean(value = "user")
        public UserBean userBean() {
        return new UserBean();
    }
    @Bean
        @Conditional(value = IOCConditional.class)
        public CarBean carBean() {
        return new CarBean();
    }
}
package com.springIOC5.config;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class IOCConditional implements Condition {
    @Override
        public Boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        if (context.getBeanFactory().containsBean("user")) {
            
            return true;
        }
        return false;
    }
}

The above code What does it mean? That is, whether we need to inject carBean, if this object contains user, you inject our carBean, does not contain the injection, there is a sense of things, Configuration Configuration injected in the class is in order, we must put our condition as a judge the Bean on top, otherwise you do not have that recognizes Conditional Bean judging criteria.

6. @ Import introducing ways injection Bean

package com.springIOC6.config;

import com.springIOC6.bean.CarBean;
import com.springIOC6.bean.UserBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({
    CarBean.class, UserBean.class
}
)
public class MainConfig {
}

We write notes directly in the class can be injected, can also use the interface to achieve, let's change it.

package com.springIOC6b.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({
    ImportSelector.class
}
)
public class MainConfig {
}
package com.springIOC6b.config;

import org.springframework.core.type.AnnotationMetadata;

public class ImportSelector implements org.springframework.context.annotation.ImportSelector {
    @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{
            "com.springIOC6b.bean.CarBean","com.springIOC6b.bean.UserBean"
        }
        ;
    }
}

Achieve ImportSelector class, and then returns the full path to the class name. Automatic assembly is based @Import implementation.

Achieve ImportBeanDefinitionRegistrar, rewrite registerBeanDefinitions methods, it is also possible.

package com.springIOC6c.config;

import com.springIOC6c.bean.CarBean;
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;

public class ImportSelectorRegister implements ImportBeanDefinitionRegistrar {
    @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(CarBean.class);
        registry.registerBeanDefinition("CarBean",rootBeanDefinition);
    }
}

7. By injecting FactoryBean

package com.springIOC7.config;

import com.springIOC7.bean.UserBean;
import org.springframework.beans.factory.FactoryBean;

public class IOCFactoryBean implements FactoryBean<UserBean> {
    @Override
        public UserBean getObject() throws Exception {
        
        return new UserBean();
    }
    @Override
        public Class<?> getObjectType() {
        
        return UserBean.class;
    }
    @Override
        public Boolean isSingleton() {
        
        return true;
    }
}
package com.springIOC7.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {
    @Bean
        public IOCFactoryBean iocFactoryBean(){
        return new IOCFactoryBean();
    }
}
package com.springIOC7;

import com.springIOC7.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext(MainConfig.class);
        Object carBean = aca.getBean("iocFactoryBean");
        
        System.out.println(carBean);
        Object iocFactoryBean = aca.getBean("&iocFactoryBean");
        
        System.out.println(iocFactoryBean);
    }
}

When it comes to all this add components to the IOC container all the way to the finish, briefly summarize:

  • @Bean injection, four kinds of scope may specify a single embodiment, many cases of (IOC container life cycle management is not), and a request for a session, may be provided lazy loading,
  • @ComponentScan specify how to scan packet injection, with the @ Controller, @ Repository, @ Service, @ Component annotations to use.
  • @Import injection mode, and the two implementation classes ImportSelector ImportBeanDefinitionRegistrar two ways.
  • @FactoryBean, engineering Bean manner can also be injected. Note is made without & ultimate object is to obtain real band & Bean. Three methods, a specified object, a specified type, specify whether a single embodiment.

For a single bean instance, then, when the container starts, bean object is created, and destroyed when the container is also called Bean's destruction methods.

For multi-instance bean, then start the container when the bean is not created but are created when acquiring bean, bean and management of destruction from IOC container.

1. Let's look at the most simple method, with initMethod and destroyMethod to specify our initialization methods and methods of destruction

package com.springlifeCycle1a.config;

import com.springlifeCycle1a.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MainConfig {
    @Bean(initMethod = "init",destroyMethod = "destroy")
        public CarBean car() {
        return new CarBean();
    }
}

We specify our initial init method, destroy method to destroy method. Call to order is, Car constructor, Car init method, Car of the destroy method, you can also try using @Lazy own annotations. Code code, there are clouds you can go try.

2. InitializingBean and DisposableBean two interface bean initialization and destruction methods

package com.springlifeCycle2a.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class CarBean implements InitializingBean, DisposableBean {
    public CarBean() {
        System.out.println("我是Car");
    }
    public void afterPropertiesSet() {
        System.out.println("我是初始化init");
    }
    public void destroy() {
        System.out.println("我是销毁destroy");
    }
}

Annotations and @PostConstruct @ProDestory 3. JSR250 standard notes provided by the method of

package com.springlifeCycle3.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class CarBean {
    public CarBean() {
        System.out.println("我是Car");
    }
    @PostConstruct
    public void init() {
        System.out.println("我是初始化init--PostConstruct");
    }
    @PreDestroy
    public void destory() {
        System.out.println("我是销毁destroy--PreDestroy");
    }    
}

4. postprocessor bean by the Spring of BeanPostProcessor will intercept all bean creation (source behind this method of speaking time will be implemented internally to talk, feel the need to look at the source code)

package com.springlifeCycle4.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class LifeBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("初始化方法" + beanName);
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("销毁方法" + beanName);
        return bean;
    }
}

There is also sum up, initialization methods within the container objects and methods of destruction of our way to specify a total of four

  • With @Bean of initMethod and destroyMethod be given as the initial method and destroy method.
  • Implementation bean initialization and destruction methods by InitializingBean and DisposableBean two interfaces.
  • @PostConstruct annotations and method provided by the labels @ProDestory JSR250 specification.
  • Postprocessor bean by the Spring of BeanPostProcessor will intercept all bean creation process.

Here's something much, I would say about the matter as soon as possible, the assignment of three ways that we look at.

package com.springValue.config;

import com.springValue.bean.CarBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource(value = "classpath:carBean.properties",encoding = "utf-8") //指定外部文件的位置
public class MainConfig {
    @Bean
    public CarBean carBean() {
        return new CarBean();
    }
}
import org.springframework.beans.factory.annotation.Value;

public class CarBean {
    @Value("宝马")
    private String name;
    @Value("#{5-2}")
    private int carNum;
    @Value("${carBean.realName}")
    private String realName;        
}

It is worth mentioning is the best set about the import file encoding = "utf-8", otherwise the characters will be garbled.

Active assembly is usually most familiar with is also the largest, let's review.

1. @ Autowired automatically when the first assembly is assembled in accordance with the type of, if a plurality of the same type found in the IOC container assembly, then to be assembled in accordance with the attribute name

package com.springxAutowired1.config;

import com.springxAutowired1.dao.AutowiredDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value = "com.springxAutowired1.service")
public class MainConfig {
    @Bean
    public AutowiredDao autowiredDao1(){
        return new AutowiredDao(1);
    }
    @Bean
    public AutowiredDao autowiredDao2(){
        return new AutowiredDao(2);
    }
}
package com.springxAutowired1.service;

import com.springxAutowired1.dao.AutowiredDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ServiceBean {
    @Autowired
    private AutowiredDao autowiredDao2;
    public ServiceBean() {
        System.out.println("我是serviceBean");
    }
    @Override
    public String toString() {
        return "ServiceBean{" +
                "AutowiredDao=" + autowiredDao2 +
                '}';
    }
}

Here we set the target of two AutowiredDao, identified as a 1, a labeled 2, ServiceBean default by name to the assembly.

2. We can also specify the name of the assembly by @Qualifier.

package com.springxAutowired1b.service;

import com.springxAutowired1b.dao.AutowiredDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class ServiceBean {
    @Autowired
    @Qualifier(value = "autowiredDao1")
    private AutowiredDao autowiredDao2;
    public ServiceBean() {
        System.out.println("我是serviceBean");
    }
    @Override
    public String toString() {
        return "ServiceBean{" +
                "AutowiredDao=" + autowiredDao2 +
                '}';
    }
}

3. We use Qualifier If the name is wrong, wrong assembly might be an error, then we can use required = false to prevent abnormal thrown

package com.springxAutowired3.service;

import com.springxAutowired3.dao.AutowiredDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class ServiceBean {
    @Qualifier(value = "autowiredDaoError")
    @Autowired(required = false)
    private AutowiredDao autowiredDao2;
    public ServiceBean() {
        System.out.println("我是serviceBean");
    }
    @Override
    public String toString() {
        return "ServiceBean{" +
                "AutowiredDao=" + autowiredDao2 +
                '}';
    }
}

Note: I did not say here @Resource annotation, this annotation is in fact not in the spring, is the JSR250 standard, but does not support the support @Primary and @Qualifier

Sometimes we need to switch our configuration through different environments, we passed @Profile notes to be activated identify different Bean depending on the environment,

@Profile logo on the class, only matching the current environment, the entire class configuration takes effect

@Profile logo on Bean, Bean then only the current environment will be activated

package com.springxAutowired4.config;

import com.springxAutowired4.bean.Environment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
public class MainConfig {
    @Bean
    @Profile(value = "test")
    public Environment environment_test() {
        return new Environment("test");
    }
    @Bean
    @Profile(value = "dev")
    public Environment environment_dev() {
        return new Environment("dev");
    }
    @Bean
    @Profile(value = "pro")
    public Environment environment_pro() {
        return new Environment("pro");
    }
}

The method of activating the switching environment

  • Method a: switched -Dspring.profiles.active = test, dev by jvm runtime parameters, prod plurality of parameter tables English intermediate comma separated
  • Method II: is activated by way of the code
package com.springxAutowired4;

import com.springxAutowired4.config.MainConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {
    /**
     * 环境切换
     * @param args
     */
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aca = new AnnotationConfigApplicationContext();
        aca.getEnvironment().setActiveProfiles("test","dev");//方便演示,我写了两个,一般都是一个的.
        aca.register(MainConfig.class);
        aca.refresh();
        for (String beanDefinitionName : aca.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
    }
}

If both are written, the code is implemented in accordance with the parameters no longer works


"A short step, a thousand miles," hope in the future you can: have a dream horse habitat everywhere! Come on, Junior!

No public concern: "Java confidant" , updated daily Java knowledge Oh, look forward to your arrival!

  • Send " Group ", progress with 100,000 programmers.
  • Send " interview " to receive information BATJ interview, video interview Raiders.
  • Send " Fun algorithm " to receive "Fun algorithm" series of video tutorials.
  • Do not send " 1024 " ...

Guess you like

Origin www.cnblogs.com/java-friend/p/11582999.html