Spring Container, Spring Objects and SpringIOC

Spring: It is an open source lightweight application framework whose purpose is to simplify enterprise-level application development and reduce intrusiveness; its essence is to manage objects in software, and to create and maintain the relationship between objects.
Spring container: used to manage objects; itself is an object; is the core of the IOC

In spring, any Java class and JavaBean are treated as beans, and these beans are managed and used by the container; the spring container implements the IOC and AOP mechanisms, which can simplify the creation of bean objects and the direct decoupling of bean objects; the spring container There are two types of BeanFactory and ApplicationContext.

JavaBean: a simple canonical Java object

What is JavaBean?
Classes that meet the following specifications:
1. Have a package
2. Have a default constructor
3. Implement the serialization interface Serializable
4. Have get/set methods

Instantiation of Spring container: ApplicationContext is integrated from the BeanFactory interface and has more enterprise-level methods. It is recommended to use this class. The instance methods are as follows:

//Load the configuration file instantiation under the project classpath
ApplicationContext ctx = new ClassPathXmlApplicationContext("app.xml");

Spring container management of beans (objects):

Bean instantiation:

1. Constructor method:

<!-- Springc creates object -->
	<!-- 1. Create an object through the constructor: class is the type of object to be created-->
	<bean class="java.util.ArrayList" id="obj1"></bean>
//Test in junit's test code
        List list = (List) ctx.getBean("obj1");
		System.out.println(list);

Note: The id or name attribute is used to specify the bean name, which is used to find the bean object from Spring; the class is used to specify the bean type, and the object will be automatically created with a no-argument constructor.

2. Static factory method:

<!-- 2. Create an object through a static factory method and call a static method of a certain class to create an object; class: the class to be called, factory-method: the static method to be called -->
	<bean class="java.util.Calendar" factory-method="getInstance" id="obj2"></bean>
// test code
    Calendar c = (Calendar) ctx.getBean("obj2");
		System.out.println(c);
		Date s = c.getTime();
		System.out.println(s);

Note: The id attribute is used to specify the bean name; the class attribute is used to specify the factory type; the factory-method attribute is used to specify the method for creating a bean object in the factory, which must be modified with static.

3. Instance factory method:

<bean factory-bean="obj2" factory-method="getTime" id="obj3"></bean>
 Date d = (Date) ctx.getBean("obj3");
		System.out.println(d);

Note: id is used to specify the bean name; the factory-bean attribute is used to specify the factory bean object; the factory-method attribute is used to specify the method for creating the bean object in the factory.

Bean naming:

In the spring container, each bean needs to have a name (ie identifier), which can be implemented with the id of the <bean> element or the attribute.

Bean alias: In order to add another name to the defined bean, you can use <alias> to specify; for example:

<alias name="fromName" alias="toName>
Bean scope:

When Spring instantiates beans in the container, it can create the following scoped bean objects:

singleton: one bean corresponds to one object instance in each Speing IOC container, the default item;

prototype: a bean definition corresponds to multiple object instances;

request: In an HTTP request, a bean definition corresponds to an instance, limited to the Web environment;

session: In an HTTP Session, a bean definition corresponds to an instance, limited to the Web environment;

global Session: In a global HTTP Session, a bean definition corresponds to an instance; only meaningful in prothet-based web applications;

The above Bean scope can be specified through the scope attribute defined by <bean>; as follows:

<bean class="java.util.HashMap" id="obj4" scope="singleton"></bean>
    /**
	 * The scope of the bean:
	 * Each bean is a singleton by default in the container
	 */
	@Test
	public void test4(){
		//1. Create a Spring container
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		// get bean
		Map map1 = (Map) ctx.getBean("obj4");
		Map map2 = (Map) ctx.getBean("obj4");
		System.out.println(map1==map2);
	}
Manage the life cycle of the bean: let spring automatically call the initialization and destruction methods of the bean
<bean class="bean.Example" id="exa" init-method="init" scope="singleton" lazy-init="true"></bean>

init-method: Declare the destruction method, which is automatically called when the container is closed.
Destory-method: Declare the destruction method, which is automatically called when the container is closed. But only valid for singleton beans

// test code
	/**
	 * Container managed bean life cycle
	 */
	@Test
	public void test5(){
		//1. Create a container
		//classPathXmlApplicationContext inherits from AbstractApplicationContext
		//The latter implements ApplicationContext.
		//AbstractApplicationContext has a method close to close the container
		AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		System.out.println("1-----");
		// get bean
		Example exa = (Example) ctx.getBean("exa");
		System.out.println(exa);
		System.out.println("2---");
		ctx.close();
	}
Bean lazy instantiation: suitable for singleton objects that are rarely used
<bean id="exampleBean" lazy-init="true" class="com.foo.ExampleBean"/>

If you don't want the singleton bean to be instantiated early when the ApplicationContext is initialized, you can use lazy instantiation.

lazy-init: lazy initialization, that is, the bean is not created when the container is created, but is created when the bean is acquired, and the timing of bean creation is postponed, which is only valid for singleton beans.

Spring container working process:

SpringIOC:

The full name of ioc is Intersion of Control, which is translated as Inversion of Control; it refers to the inversion of the acquisition method of objects in the program, which is created by the original new method and transformed into created and injected by a third-party framework (DI), which reduces the The degree of coupling between objects.

Spring container is controlled by DI method like IOC, IOC is the foundation and core of Spring framework;

The full name of DI is Dependency Injection, which is called Dependency Injection; the basic principle is that objects that work together have a relationship, and the association is established by passing in the constructor parameters or method parameters, so the job of the container is to inject those dependencies when creating beans.

IOC is an idea, and DI is the main technical way to realize IOC; DI mainly has two injection methods, namely setter injection and constructor injection;

Setter injection: After instantiating the bean by calling the no-parameter constructor or the no-parameter static factory method , call the setter method of the bean to achieve setter injection

<!-- 1.setter injection: inject parameters into it through the bean's set method -->
	<bean class="bean.Computer" id="computer">
		<property name="mainboard" value="技嘉"/>
		<property name="hdd" value="希捷"/>
		<property name="ram" value="金士顿"/>
	</bean>
/**
	 * Dependency injection - setter injection
	 */
	@Test
	public void test6(){
		//create container
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		Computer com = (Computer) ctx.getBean("computer");
		System.out.println(com);
		System.out.println(com.getHdd()+";"+com.getHdd()+";"+com.getRam());
	}
package bean;

public class Computer {
	private String mainboard;
	private String hdd;
	private String ram;
	public String getMainboard() {
		return mainboard;
	}
	public void setMainboard(String mainboard) {
		this.mainboard = mainboard;
	}
	public String getHdd() {
		return hdd;
	}
	public void setHdd(String hdd) {
		this.hdd = hdd;
	}
	public String getRam() {
		return ram;
	}
	public void setRam(String ram) {
		this.ram = ram;
	}
	
}

Constructor injection: Constructor-based injection is implemented by calling the constructor with parameters. When the bean is instantiated, the container executes the corresponding constructor according to the parameter type; Constructor injection can force the bean to inject certain parameters. Parameters, which are stricter than Setter injection, are often used to force injection of these parameters.

xml and test:

<bean class="bean.MobilePhone" id="phone">
		<constructor-arg index="0" value="ARM"/>
		<constructor-arg index="1" value="4G"/>
	</bean>
	@Test
	public void test7(){
		//create container
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		MobilePhone phone = (MobilePhone) ctx.getBean("phone");
		System.out.println(phone);
		System.out.println(phone.getCpu()+";"+phone.getRam());
	}

Entity class:

package bean;

import java.io.Serializable;

public class MobilePhone implements Serializable{
	
	private String cpu;
	private String ram;
	
	
	public MobilePhone(String cpu, String ram) {
		this.cpu = cpu;
		this.ram = ram;
	}
	public String getCpu() {
		return cpu;
	}
	public void setCpu(String cpu) {
		this.cpu = cpu;
	}
	public String getRam() {
		return ram;
	}
	public void setRam(String ram) {
		this.ram = ram;
	}
	
}

Autowiring: The Spring Ioc container can autowire ( autowire ) the relationship between cooperating beans. Autowire can be set for a single bean. The convenience of autowire is to reduce the xml injection configuration; in the xml configuration file, you can use <bean The autowire attribute is used in the /> element to specify the autowiring rule. There are 5 types of values :

<!-- Autowiring: When Spring creates a bean, it can find a matching bean from the container according to the type or name, and set it to the bean property, you need to create the corresponding Student class -->
	<bean class="bean.Student" id="student" autowire="byType"></bean>
/**
	 * Automatic assembly
	 */
	@Test
	public void test8(){
		//create container
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		Student s = (Student) ctx.getBean("student");
		System.out.println(s.getComputer().getMainboard());
		System.out.println(s.getPhone().getCpu());
	}

no: disable autowiring;

byName: Autowire according to the property name, this option will check the container and find the bean that is exactly the same as the property according to the name, and autowire it with the property;

byType: If there is a bean of the same type as the specified property in the container, it will be autowired with the property;

constructor: similar to the way byType, except that it is applied to the constructor parameters

autodetect: Use the bean class to decide whether to use the constructor or the byType method for automatic assembly. If the default constructor is found, the byType method will be used;

Parameter value injection:

<!-- parameter value injection -->
	<bean class="bean.Message" id="msg">
		<!-- Inject basic values: basic types, encapsulated types, String types -->
		<property name="id" value="1"/>
		<property name="name" value="zhangsan"/>
		<property name="sal" value="50000.00"/>
		<!-- Injected beans (provided they are all in the container and must be created by the container); name: the name of the property to be injected; ref: the ID of the injected bean -->
		<property name="phone" ref="phone"/>
		<!-- Inject collection List, Set, Map, Properties -->
		<property name="cities">
			<list>
				<value>北京</value>
				<value>上海</value>
				<value>广州</value>
			</list>
		</property>
		<property name="score">
			<map>
				<entry key="张三" value="101KG"/>
				<entry key="李四" value="102KG"/>
			</map>
		</property>
		<property name="params">
			<props>
				<prop key="user">system</prop>
				<prop key="password">dream</prop>
			</props>
		</property>
	</bean>
	/**
	 * Parameter value injection
	 */
	@Test
	public void test9(){
		//create container
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		Message msg = (Message) ctx.getBean("msg");
		System.out.println(msg.getId());
		System.out.println(msg.getName());
		System.out.println(msg.getSal());
		System.out.println(msg.getPhone().getCpu());
		System.out.println("城市:"+msg.getCities().get(0));
		System.out.println("体重:"+msg.getScore().get("张三"));
		System.out.println("参数:"+msg.getParams().getProperty("user"));
	}

Annotation-based dependency injection:

When it comes to annotations, we have to talk about component scanning; component scanning is to formulate a package path, and Spring will automatically scan all component classes in the package and its subpackages. The Spring container is equivalent to the <bean> definition function in the original XML configuration; component scanning can replace the <bean> definition of a large number of XML configurations.

Specify the component scan path:

<!--To use the component face, you first need to specify the scan parent package path in the XML configuration-->
<context:component-scan base-package="org.example"/>

With the above configuration, the container will automatically scan all components under the org.example package and its subpackages, and instantiate them as beans.

Automatically scanned annotation tags: Only when there is an annotation tag in front of the component class definition will it be scanned into the Spring container.

@Component: generic annotation

@Named: generic annotation

@Repository: Persistence layer component annotation

@Service: business layer component annotation

@Controller: control layer component annotation

Naming of automatic scanning components: (two kinds)

@Component //The default id is the class name starting with lowercase
public class ExampleBean implements Serializable{
}   

@Component("example") //custom id
public class ExampleBean implements Serializable{
}       

Scope of custom components:

@Component
@Scope("prototype")
public class ExampleBean implements Serializable{

}

Note: For components managed by spring, the default scope is "singleton", if other @Scope annotations are available.

Custom initialization and destruction callbacks:

/**
 * @author dream-it
 * Demo component scan
 */
//General annotation, indicating that it can be used anywhere. After adding it, spring will manage the Student as a bean
//The configuration file will automatically generate a bean, the default ID is the class name after the first letter is lowercase
@Component("stu")
//indicates the scope
@Scope("singleton")
// lazy loading
@Lazy(true)
public class Student {
	
	//Initialization method
	@PostConstruct
	public void init(){
		System.out.println("Student的init()...");
	}
	
	// destroy method
	@PreDestroy
	public void destory(){
		System.out.println("Destruction of Student");
	}
	
	public Student() {
		System.out.println("Student's parameterless constructor...");
	}
	
}

Dependency injection (using annotations): mainly in 3 ways;

1. AutoWired and Qualifier (divided into two types written in front of the constructor and set method)

@Autowired is written in front of the constructor, declaring that you need to inject beans for it

@Qualifier is written in front of the parameter, declaring the ID value of the bean to be injected

@Component("rest")
public class Restaurant {
	//These two annotations can also be added directly to the front of the property
	//At this time, the corresponding set method can be omitted and executed through the reflection mechanism
	@Autowired
	//wt represents the ID of the injected bean
	@Qualifier("wtm")
	private Waiter wt;	

Test class:

	@Test
	//Test @AutoWired to complete the annotation
	public void test5(){
		ApplicationContext ctx = new ClassPathXmlApplicationContext("app.xml");
		Restaurant rest = ctx.getBean("rest",Restaurant.class);
		System.out.println(rest);
		Hotel hotel = ctx.getBean("hotel",Hotel.class);
		System.out.println(hotel);
	}

Note: When the injected object is a singleton, @Qualifier can be omitted. In this case, Spring matches parameters by type

@Autowired is written in front of the set method, declaring that you need to inject beans for it

@Qualifier is written in front of the parameter, declaring the ID value of the bean that needs to be tracked

@Component("rest")
public class Restaurant {
  private Waiter wt;
  @Autowired
  public void setWt(@Qualifier("wt") Waiter wt) {
  System.out.println("Res set method");		
  this.wt = wt;
}
2. @Inject annotation: Same as @Autowired function, but additional guide package is required when using it

The @Inject annotation mark is the support for the JSR-330 standard added by Spring 3.0. Before use, you need to add the JSR-330 jar package javax.inject-1.jar

The @Inject annotation usage is the same as @Autowired, where

1).@Inject is equivalent to @Autowired;

2).@Named is equivalent to @Qualifier

3. @Resource annotation: (can only be used for setter injection, but it is simpler and more important, because it is generally setter injection)
@Component
public class Manager implements Serializable{
   private Computer computer;
   @Resource(name="computer")
   public void setComputer(Computer computer){
   this.computer = computer;
   System.out.println("Manager");
  }
}

Note: 1. When the injected object is a singleton, (name="computer") can be omitted. In this case, the Spring installation type matches the parameter

          2. @Resource can also be written on properties, which is similar to writing on set methods, but only executes one line of code: this.computer = computer;

Summarize:

The Spring container is equivalent to a large abstract factory. It is very complicated to create objects in the program, so there will be corresponding design patterns. The Spring container is equivalent to taking the objects and using the framework to help you manage them, which greatly reduces the coupling degree of the program; and the Spring container implements the mechanisms of IOC and AOP, making it easy to create objects and extend them, and also Comply with the open-closed principle. And using SpringIOC's DI method to inject objects also greatly reduces the coupling of the program.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325944361&siteId=291194637