preface

Anyone who has studied the Spring framework will have heard of the concept of IOC(Inversion of Control) in Spring. For beginners, IOC is often ambiguous and difficult to understand. Today, I would like to share with you my understanding of Spring IOC and the understanding of some technical leaders on the Internet about Spring framework IOC.

Content covers: Java, MyBatis, ZooKeeper, Dubbo, Elasticsearch, Memcached, Redis, MySQL, Spring, SpringBoot, SpringCloud, RabbitMQ, Kafka, Linux and other technology stacks.

Full version Java interview questions address: Java backend questions integration

What is the IOC

It’s not an IOC — it’s an Inversion of Control idea. In Java development, IOC means handing your designed objects over to the container for control, rather than the traditional direct control within your objects. How to understand IOC? The key to a good understanding of IOC is to be clear about “who controls whom, what controls, why there is a reversal (there should be a positive reversal), which aspects of the reversal”. Then let’s have an in-depth analysis:

(1) Who controls who, controls what: traditional Java SE programming, we directly create objects in the object through new, is the program to create dependent objects; IoC has a special container to create these objects, that is, the IoC container controls the creation of objects; Who controls whom? The IoC container, of course, controls the objects; Control what? That is, it mainly controls the acquisition of external resources (not just objects including files, etc.).

(2) Why is the inversion, which aspects of the inversion: there is inversion, there is forward, traditional application is by our own active control in the object to directly obtain the dependent object, that is, forward; In inversion, the container helps create and inject dependent objects. Why reverse? Because the container helps us find and inject the dependent object, the object only passively accepts the dependent object, so it is inversion; What has been reversed? The retrieval of dependent objects has been reversed.

As an illustration, traditional programming diagrams actively create related objects and then combine them:

Once the IOC container is in place, these objects are no longer actively created in the client class, as shown in the figure below:

Next, let’s look at four features of IOC

1. Lazy-init lazy loading

Lazy loading of Bean objects (lazy creation)

The default behavior of the ApplicationContext container is to instantiate all Singleton beans ahead of time when the server is started. Pre-instantiation means that all singleton beans are created and configured by the ApplicationContext instance as part of the initialization process. Full version Java interview questions address: Java backend questions integration

1.1 Enabling Lazy Loading in XML Mode:

Lazy-init =”” configures lazy loading of bean objects, true or false. False means immediate loading

< bean id = "lazyResult" class = "com.lagou.edu.pojo.Result" lazy - init = "false" > < / bean > duplicate codeCopy the code

Let’s take a look at lazy-init=”false”, which is loaded immediately:

As you can see, the lazyResult bean already exists after the container is started and before the getBean.

And then we set lazy-init=”true” to true

Then let’s F8 take a step down:

LazyResult was found

1.2 Comments enable lazy loading:

@ Lazy:

1.3 Global configuration — default-lazy-init=””

In the bean root tag:

Application scenarios: (1) Enable lazy loading to improve the container startup and operation performance to a certain extent. (2) Enable lazy loading for beans that are not commonly used, so that they can be loaded when they are occasionally used, and the Bean does not need to occupy resources from the beginning

2. FactoryBean and the BeanFactory

2.1 the BeanFactory

The container’s top-level interface, which defines some of the container’s basic behavior, is responsible for producing and managing a factory of beans, using subinterface types such as ApplicationContext

2.2 FactoryBean

There are two kinds of beans in Spring

Common bean

Factory beans can produce bean instances of a particular type (returned to us), which means we can customize the bean creation process.

The static and instantiation methods of Bean creation are similar to factoryBeans. Factorybeans are used a lot, especially in some components of the Spring framework, as well as other frameworks that integrate with the Spring framework

Public interface FactoryBean<T> {// Return the instance created by the FactoryBean. If isSingleton returns true, Map@Nullable T getObject() throws Exception; // Return the bean type created by FactoryBean @nullable Class<? > getObjectType(); Default Boolean isSingleton() {return true; }} Copy the codeCopy the code

2.2.1 Create CompanyFactoryBean, implement FactoryBean interface, and rewrite method:

public class CompanyFactoryBean implements FactoryBean<Company> { private String companyInfo; Public void setCompanyInfo(String companyInfo) {this.panyInfo = companyInfo; this.panyInfo = companyInfo; this.panyInfo = companyInfo; } @override public Company getObject() throws Exception {Company Company Company =new Company(); String[] split = companyInfo.split(","); company.setName(split[0]); company.setAddress(split[1]); company.setScale(Integer.parseInt(split[2])); return company; } @Override public Class<? > getObjectType() {return company.class; } @override public Boolean isSingleton() {return true; }} Copy the codeCopy the code
public class Company { private String name; private String address; private int scale; // omit the getSet and toString} copy codeCopy the code

2.2.2 Configuring beans in XML file

<bean id="companyBean" class="com.lagou.edu.factory.CompanyFactoryBean"> <property name="companyInfo" </property> </bean> Copy codeCopy the code

2.2.3 test

@org.junit.Test public void test(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); Object companyBean = applicationContext.getBean("companyBean"); System.out.println(companyBean); } Company{name=' hook ', address=' zhongguanvillage ', scale=500Copy the code

Although in the XML configuration file configured bean class = “com.lagou.edu.factory.CompanyFactoryBean” but returned to the Company type.

How do I return the CompanyFactoryBean type?

3. Rear processor

Spring provides an extended interface for two types of post-processing beans, BeanPostProcessor and BeanFactoryPostProcessor, which are used differently.

Factory initialization (BeanFactory) — > Bean object

After the BeanFactory is initialized, you can do a few things with the BeanFactoryPostProcessor postprocessing

There are some things you can do with the BeanPostProcessor after the Bean object is instantiated (and not complete for the Bean’s entire life cycle)

Note: An object is not necessarily a Springbean, and a Springbean is definitely an object

3.1 SpringBean life cycle diagram

Print as described above. See if it’s consistent:

// Implement BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean Public class Result implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean { private String status; private String message; @override public void setBeanFactory(BeanFactory) throws BeansException { System. The out. Println (" 4. BeanFactoryAware: "+ the beanFactory); } @override public void setBeanName(String name) {system.out.println ("3.BeanNameAware: "+name); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System. The out. Println (" 5. ApplicationContextAware: "+ applicationContext); } @Override public void afterPropertiesSet() throws Exception { System.out.println("7.InitializingBean"); } public void initMethodTest(){ System.out.println("8.initMethod"); } @PostConstruct public void postCoustrcut(){ System.out.println("postCoustrcut"); } @predestroy public void PreDestroy (){system.out.println (" execute before destroy "); } @Override public void destroy() throws Exception { System.out.println("DisposableBean"); }} /** Copy the codeCopy the code
Intercepts all */ @Component public class MyBeanPostProcessor implements BeanPostProcessor {@override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("lazyResult".equalsIgnoreCase(beanName)){ System.out.println("MyBeanPostProcessor before"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("lazyResult".equalsIgnoreCase(beanName)){ System.out.println("MyBeanPostProcessor After"); } return bean; }} Copy the codeCopy the code
/ / XML configuration file: < bean id = "lazyResult" class = "com.lagou.edu.pojo.Result" init - method = "initMethodTest" > < / bean > duplicate codeCopy the code
/ / test:  @org.junit.Test public void testBeanLazy(){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); Object lazyResult = applicationContext.getBean("lazyResult"); System.out.println(lazyResult); applicationContext.close(); } Duplicate codeCopy the code

Print out:

Other: 4.

Full version Java interview questions address: Java backend questions integration