spring
1. Simple explanation of coupling
Program coupling
- Coupling: dependencies between programs
- Dependencies between classes
- Dependencies between methods
- Decoupling: reducing dependencies between programs
- In actual development:
- Should be done; Compile time does not depend, run time does
- Decoupling idea:
- The first step is to use reflection to create objects instead of the new keyword.
- The second step is to obtain the fully qualified class name of the object to be created by reading the configuration file
package xyz.slienceme.jdbc; import java.sql.*; /** * @Author slience_me * @Time : 2021/6/26 17:45 * @File : JdbcDemo1.java * @Software : IntelliJ IDEA * @MyBlog : https://blog.csdn.net/slience_me */ public class JdbcDemo1 { public static void main(String[] args) throws SQLException, ClassNotFoundException { //1. Register driver // DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver()); Class.forName("com.mysql.cj.jdbc.Driver"); //2. Get connection Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/eesy","root","root"); //3. Get the preprocessing object of the operation database PreparedStatement pstm = conn.prepareStatement("select * from account"); //4. Execute SQL to get the result set ResultSet rs = pstm.executeQuery(); //5. Traversal result set while (rs.next()){ System.out.println(rs.getString("name")); } //6. Release resources rs.close(); pstm.close(); conn.close(); } }
Factory decoupling (Dao & daoimpl | Service & serviceimpl)
accountService=xyz.slienceme.service.impl.AccountServiceImpl accountDao=xyz.slienceme.dao.impl.AccountDaoImpl
/** * @Author slience_me * @Time : 2021/6/27 8:50 * Business layer implementation class of account */ public class AccountServiceImpl implements IAccountService { private IAccountDao accountDao = (IAccountDao) BeanFactory.getBean("accountDao"); }
/** * @Author slience_me * @Time : 2021/6/27 8:56 * Simulate a presentation layer for calling the business layer */ public class Client { public static void main(String[] args) { IAccountService as = (IAccountService) BeanFactory.getBean("accountService"); } }
- A factory that creates Bean objects
- Bean: in computer English, it means reusable component.
- JavaBean s: reusable components written in the java language.
- JavaBean > entity class
- It creates our service and dao objects.
- First, we need a configuration file to configure our service and dao
- The second is to create reflection objects by reading the configured contents in the configuration file
- My configuration file can be xml or properties
package xyz.slienceme.factory; import sun.misc.ExtensionInstallationException; import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * @Author slience_me * @Time : 2021/6/27 9:00 */ public class BeanFactory { //Define a Properties object private static Properties props; //Define a Map to store the objects we want to create. We call it a container private static Map<String,Object> beans; //Assign a value to the Properties object using static code static { try { //Instantiate object props = new Properties(); //Gets the stream object of the properties file InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"); props.load(in); //Instantiate container beans = new HashMap<String,Object>(); //Remove all keys from the configuration file Enumeration keys = props.keys(); //Traversal enumeration while (keys.hasMoreElements()){ //Remove each key String key = keys.nextElement().toString(); //Get value according to key String beanPath = props.getProperty(key); //Create objects with reflections Object value = Class.forName(beanPath).newInstance(); //Store the key and value in the container beans.put(key,value); } }catch (Exception e){ throw new ExceptionInInitializerError("initialization properties Failed!"); } } /** * Gets the object based on the name of the bean * @param beanName * @return */ public static Object getBean(String beanName){ return beans.get(beanName); } /*public static Object getBean(String beanName){ Object bean = null; try { String beanPath = props.getProperty(beanName); bean = Class.forName(beanPath).newInstance(); } catch (Exception e){ e.printStackTrace(); } return bean; }*/ }
2. spring implementation
bean.xml configuration file
<?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"> <!--Leave the creation of objects to spring To manage--> <bean id="accountService" class="xyz.slienceme.service.impl.AccountServiceImpl"/> <bean id="accountDao" class="xyz.slienceme.dao.impl.AccountDaoImpl"/> </beans>
Simulate a presentation layer for calling the business layer
-
Get the Ioc core container of the spring container, and get the object according to the id
-
Three common implementation classes of ApplicationContext:
- ClassPathXmlApplicationContext: it can load the configuration file under the classpath. It is required that the configuration file must be under the classpath. It can't be loaded without you
- FileSystemXmlApplicationContext: it can load configuration files under any path on the disk (must have access rights)
- AnnotationConfigApplicationContext: it is used to read annotations and create containers
-
Problems caused by two interfaces of the core container
- The ApplicationContext singleton object uses this interface
- When it builds the core container, the strategy of creating objects is to load immediately, that is, the configuration objects in the configuration file will be created as soon as the configuration file is read
- BeanFactory multi instance objects use this interface
- When it builds the core container, the strategy of creating objects is to load immediately, that is, when the object is obtained according to the id and when the object is really created.
- The ApplicationContext singleton object uses this interface
package xyz.slienceme.ui; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import xyz.slienceme.dao.IAccountDao; import xyz.slienceme.factory.BeanFactory; import xyz.slienceme.service.IAccountService; import xyz.slienceme.service.impl.AccountServiceImpl; /** * @Author slience_me * @Time : 2021/6/27 8:56 * Simulate a presentation layer for calling the business layer */ public class Client { public static void main(String[] args) { //1. Get the core container object ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //2. Get Bean object according to id IAccountService as = (IAccountService)ac.getBean("accountService"); IAccountDao adao = ac.getBean("accountDao",IAccountDao.class); System.out.println(as); System.out.println(adao); // as.saveAccount(); } }
Three configuration methods of bean
- Leave the creation of objects to spring to manage
- spring bean management details
1. There are three ways to create bean s
2. Scope of bean object
3. Life cycle of bean object - Three ways to create beans
<?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"> <!-- The first way: use the default constructor to create. stay spring Used in the configuration file bean Label with id and class After attribute, and there are no other attributes and labels, The default constructor is used to create bean Object. At this time, if there is no default constructor in the class, the object cannot be created. <bean id="accountService" class="xyz.slienceme.service.impl.AccountServiceImpl"></bean> --> <!-- The second way , Use the methods in the normal factory to create objects (use the methods in a class to create objects and store them in the spring (container) <bean id="instanceFactory" class="xyz.slienceme.factory.InstanceFactory"/> <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"/> --> <!-- The third way , Use the static methods in the static factory to create objects (use the static methods in a class to create objects and store them in the spring (container)--> <bean id="accountService" class="xyz.slienceme.factory.StaticFactory" factory-method="getAccountService"/> </beans>
package xyz.slienceme.factory; import xyz.slienceme.service.IAccountService; import xyz.slienceme.service.impl.AccountServiceImpl; /** * @Author slience_me * @Time : 2021/6/29 8:55 * Simulate a factory class (this class may exist in the jar package, and we cannot provide the default constructor by modifying the source code) */ public class InstanceFactory { public IAccountService getAccountService(){ return new AccountServiceImpl(); } }
Scope adjustment of bean
- scope attribute of bean tag:
- Scope: used to specify the scope of the bean
- Value: single instance and multi instance are commonly used
- Singleton: singleton (default)
- prototype: multi instance
- Request: the scope of the request applied to the web application
- session: the range of sessions used for web applications
- Global session: the session scope (global session scope) that acts on the cluster environment. When it is not a cluster environment, it is a session
<?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="accountService" class="xyz.slienceme.service.impl.AccountServiceImpl" scope="prototype"/> </beans>
The lifecycle of the bean object
- Singleton object
- Birth: the object is born when the container is created
- Alive: the object is alive as long as the container is still there
- Death: the container is destroyed and the object dies
- Summary: the lifecycle of a singleton object is the same as that of a container
- Multi instance object
- Birth: the spring framework creates for us when we use objects
- Alive: an object is alive as long as it is in use
- Death: when the object is not used for a long time and there is no other object reference, it is collected by the java garbage collector
<?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="accountService" class="xyz.slienceme.service.impl.AccountServiceImpl" init-method="init" destroy-method="destroy" scope="prototype"/> </beans>
Dependency injection in spring
- Dependency injection:
- Dependency Injection
- Role of IOC:
- Reduce coupling (dependencies) between programs
- Dependency management:
- In the future, it will be left to spring for maintenance
- The objects of other classes need to be used in the current class, which are provided by spring. We only need to explain it in the configuration file
- Dependency maintenance:
- It is called dependency injection.
- Dependency injection
- Data that can be injected: there are three types
- Basic type and String
- Other bean types (configured beans in the configuration file or annotated)
- Complex type / collection type
- Injection method:
- The first is to use the constructor to provide
- The second method: use the set method to provide
- The third method: using annotation to provide
- Data that can be injected: there are three types
public class Client { public static void main(String[] args) { //1. Get the core container object ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //2. Get Bean object according to id IAccountService as = (IAccountService)ac.getBean("accountService"); as.saveAccount(); } }
Injection method:
The first is to use the constructor to provide:
- Constructor injection:
- Tag used: constructor ARG
- Where the tag appears: inside the bean tag
- Attributes in Tags
- Type: used to specify the data type to be injected, which is also the type of one or some parameters in the constructor
- Index: used to specify the parameter assignment of the specified index position in the data constructor to be injected. The location of the index starts at 0
- Name: used to specify the parameter assignment of the specified name in the data constructor to be injected. The location of the index is from 0 (commonly used)
- The above three are used to assign a value to which parameter in the constructor
- value: used to provide data of basic type and String type
- ref: used to specify other bean type data. It specifies the bean objects that appear or in the IOC core container of spring
- Advantages:
- When obtaining a bean object, injecting data is a necessary operation, otherwise it cannot be created successfully.
- Disadvantages:
- The instantiation method of bean object is changed, so that if we can't use these data when creating an object, we must also provide them.
package xyz.slienceme.service.impl; import xyz.slienceme.service.IAccountService; import java.util.Date; /** * @Author slience_me * @Time : 2021/6/27 8:50 * Business layer implementation class of account */ public class AccountServiceImpl implements IAccountService { //If the data changes frequently, it is not suitable for injection private String name; private Integer age; private Date birthday; public AccountServiceImpl(String name, Integer age, Date birthday){ this.name=name; this.age=age; this.birthday=birthday; } public void saveAccount() { System.out.println("name:" + this.name + ",age:"+ this.age +",birthday:"+ this.birthday); } }
<?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="accountService" class="xyz.slienceme.service.impl.AccountServiceImpl"> <constructor-arg name="name" value="test"/> <constructor-arg name="age" value="18"/> <constructor-arg name="birthday" ref="now"/> </bean> <!-- Configure a date object --> <bean id="now" class="java.util.Date"></bean> </beans>
The second method uses the set method to provide:
- set method injection is more commonly used
- Design tag: property
- Where it appears: inside the bean tag
- Attributes in Tags
- Name: used to specify the name of the set method to be called when injecting
- value: used to provide data of basic type and String type
- ref: used to specify other bean type data. It specifies the bean objects that appear or in the IOC core container of spring
- Advantages:
- There are no explicit restrictions when creating objects. You can directly use the default constructor
- Disadvantages:
- If a member must have a value, the set method may not be executed when obtaining the object.
package xyz.slienceme.service.impl; import xyz.slienceme.service.IAccountService; import java.util.Date; /** * @Author slience_me * @Time : 2021/6/27 8:50 * Business layer implementation class of account */ public class AccountServiceImpl2 implements IAccountService { //If the data changes frequently, it is not suitable for injection private String name; private Integer age; private Date birthday; public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } public void setBirthday(Date birthday) { this.birthday = birthday; } public void saveAccount() { System.out.println("name:" + this.name + ",age:"+ this.age +",birthday:"+ this.birthday); } }
<?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"> <!-- Configure a date object --> <bean id="now" class="java.util.Date"/> <bean id="accountService2" class="xyz.slienceme.service.impl.AccountServiceImpl2"> <property name="name" value="TEST"/> <property name="age" value="20"/> <property name="birthday" ref="now"/> </bean> </beans>
- Injection of complex type / injection of collection type
- Label used to inject the List structure:
- list array set
- Label used to inject into the Map structure collection:
- map props
- The structure is the same, and the labels are interchangeable
- Label used to inject the List structure:
<?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="accountService3" class="xyz.slienceme.service.impl.AccountServiceImpl3"> <property name="myStrs" > <array> <value>AAA</value> <value>BBB</value> <value>CCC</value> </array> </property> <property name="myList" > <list> <value>AAA</value> <value>BBB</value> <value>CCC</value> </list> </property> <property name="mySet" > <set> <value>AAA</value> <value>BBB</value> <value>CCC</value> </set> </property> <property name="myMap" > <map> <entry key="testA" value="aaa"/> <entry key="testB" > <value>BBB</value> </entry> </map> </property> <property name="myProps" > <props> <prop key="testC" >ccc</prop> <prop key="testD" >ddd</prop> </props> </property> </bean> </beans>
The third method: using annotations to provide:
For creating objects
- Their function is the same as that of writing a < bean > tag in the XML configuration file
- @Component
- Function: used to store the current class object into the spring container
- Properties:
- Value: used to specify the id of the bean. When we do not write, its default value is the current class name, and the initial letter is changed to lowercase.
- @Controller: generally used in the presentation layer
- @Service: generally used in the business layer
- @Repository: generally used in the persistence layer
- As like as two peas, @Component and the above three annotations are exactly the same.
- The three of them are the spring framework, which provides us with clear annotations for three-tier use, making our three-tier objects clearer
For injecting data
- Their role is the same as writing a < property > tag in the bean tag in the XML configuration file
- @Autowired:
- effect:
- Automatically inject by type. As long as there is a unique bean object type in the container that matches the variable type to be injected, the injection can succeed
- If the type of any bean in the ioc container does not match the type of the variable to be injected, an error is reported.
- If there are multiple types matching in the ioc container;
- Location:
- It can be variable or method
- Details:
- When using annotation injection, the set method is not necessary.
- @Qualifier:
- Function: inject by name based on the injection in class. It cannot be used alone when injecting class members. However, when injecting method parameters, you can
- Properties:
- value: used to specify the id of the injected bean
- @Resource:
- Function: inject directly according to the id of the bean. It can be used independently
- Properties:
- name: used to specify the id of the bean
- The above three injections can only inject data of other bean types, while the basic type and String type cannot be implemented with the above annotation.
- In addition, the injection of collection types can only be realized through XML.
- @Value:
- Function: used to inject data of basic type and String type
- Properties:
- Value: used to specify the value of the data. It can use spiel in spring (that is, spring's el expression)
- Writing method of spiel, ${expression}
Used to change the scope of action
- Their function is the same as that of using the scope attribute in the bean tag
- @Scope
- Scope: used to specify the scope of the bean
- Properties:
- Value: the value of the specified range. Common value, singleton prototype
Life cycle related knowledge
- Their role is the same as using init method and destroy method in bean tags
- @PreDestory
- Function: used to specify the destruction method
- @PostConstruct
- Function: used to specify the initialization method
package xyz.slienceme.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import xyz.slienceme.dao.IAccountDao; import xyz.slienceme.service.IAccountService; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; /** * @Author slience_me * @Time : 2021/6/27 8:50 */ @Service("accountService") @Scope("singleton") public class AccountServiceImpl implements IAccountService { // @Autowired // @Qualifier("accountDao2") @Resource(name = "accountDao2") private IAccountDao accountDao = null; @PostConstruct public void init(){ System.out.println("Initialization started"); } @PreDestroy public void destroy(){ System.out.println("The destruction method was executed"); } @Override public void saveAccount() { accountDao.saveAccount(); } }
@Repository("accountDao") public class AccountDaoImpl implements IAccountDao { public void saveAccount() { System.out.println("Saved account"); } }