Spring
1. Introduction to spring
Spring is an open source design level framework, which solves the loose coupling between the business logic layer and other layers. He applied the idea of interface oriented programming to the whole system application.
1.1 Spring features
- Convenient decoupling and simplified development
Spring provides IOC container. We can control and manage the dependency of objects by spring to avoid excessive coupling of programs caused by hard coding. With spring, you don't have to write code for the very low-level requirements such as single instance pattern classes and property file parsing. You can focus more on the upper-level applications. - AOP programming support
Through the AOP function provided by Spring, it is convenient for aspect oriented programming. Many functions that are not easy to realize with traditional OOP can be easily handled through AOP. - Declarative transaction support
In Spring, we can get rid of the tedious transaction management code and flexibly manage transactions in a declarative way to improve development efficiency and quality. - Convenient program testing
Almost all testing work can be carried out in a container independent programming way. In Spring, testing is no longer an expensive operation, but a thing to do at will. For example, Spring supports Junit4. You can easily test Spring programs through annotations. - Convenient collection of various excellent frameworks
Spring does not exclude various excellent open source frameworks. On the contrary, spring can reduce the difficulty of using various frameworks. Spring provides direct support for various excellent frameworks (such as Struts,Hibernate, Hessian, quartz, etc.). - Reduce the difficulty of using Java EE API
1.2 Spring organizational structure
1.3 core modules of spring
Spring core: the most basic implementation of dependency injection IOC and DI
Spring beans: bean factory and bean assembly
Spring context: the context of spring, i.e. IoC container
spring-context-support
spring expression: spring expression language
Spring 2 in IOC
IOC is short for Inverse of Control, which means control reversal. It is a design idea to reduce the coupling relationship between objects.
DI is the abbreviation of Dependency Injection, which means Dependency Injection. It means that when an object instance is created, the attribute it depends on is injected into the object at the same time.
2.1 implementation process
- Add jar package
<!-- Spring Core toolkit for--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.8.RELEASE</version> </dependency> <!--On the basis IOC In terms of function, it provides extended services and supports many enterprise level services, including mail service, task scheduling, remote access, cache and various view layer frameworks--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.8.RELEASE</version> </dependency> <!-- Spring IOC Basic implementation of, including access to configuration files, creation and management bean etc. --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.8.RELEASE</version> </dependency> <!-- Spring context Extended support for MVC aspect --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.0.8.RELEASE</version> </dependency> <!-- Spring Expression language --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.0.8.RELEASE</version> </dependency>
- create profile
<?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"> </beans>
- Create object in configuration file
<bean id="Object name" class="Full path to class"> <property name="Attribute name" ref="Object id value"></property> </bean>
- Load configuration file get object
ApplicationContext app = new ClassPathXmlApplicationContext("application.xml"); //Create objects through the getBean() method. By default, objects are created using the parameterless construction method UserService uservice = (UserService) app.getBean("uservice");
Summary: benefits of using IOC container to manage objects:
- There is no need to use the new keyword to create objects to reduce code coupling.
- Without changing the code, different implementation class objects can be replaced through the configuration file.
2.2 introduction to bean tag attributes
- Class - specifies the full path of the corresponding class of the bean (the full path of the interface cannot be written, after all, the interface cannot be instantiated)
- Name – name is an identifier of the bean object
- Scope – execute the pattern and life cycle of bean object creation, scope = "singleton" (single instance) and scope = "prototype" (multiple instances); singleton mode is adopted by default in Spring
- id – id is the unique identifier of the bean object, and special symbols cannot be added
- Lazy init – whether to delay loading. The default value is false. true delay loading object means that the object will be loaded only when it is called (the object will be loaded only when it is obtained through getBean()); False means that the object will be created immediately regardless of whether the object is used or not without delay.
- Init method – object initialization method
- Destruction method – object destruction method
2.3 object creation method
-
Nonparametric structure
Create objects through the getBean() method. By default, objects are created using the parameterless construction method
-
Parametric structure
//When assigning a value to an attribute, the object type uses ref and the non object type uses value <bean id="u5" class="com.wjb.bean.User"> <constructor-arg index="0" value="Zhang San"/> <constructor-arg index="1" value="19"/> </bean> <bean id="u6" class="com.wjb.bean.User"> <constructor-arg name="uname" value="Wang Wu"/> <constructor-arg name="age" value="18"/> </bean>
- Creating objects using static methods
//Static method public static Person createPerson(){ System.out.println("Creating objects in static factory mode"); return new Person(); } <bean id="u3" class="com.wjb.bean.User" factory-method="createPerson"></bean>
- Non static factory method
//Non static factory creation object public Person createPerson2(){ System.out.println("Non static factory creation object"); return new Person(); } <bean id="u4" class="com.wjb.bean.User"></bean> <bean id="u5" class="com.wjb.bean.User" factory-bean="u4" factory-method="createPerson2"></bean>
2.4 life cycle of springbean
Description of the whole execution process of Bean life cycle:
- Call the bean constructor or factory method to instantiate the bean object according to the configuration
- Use dependency injection to complete the configuration injection of all attribute values in the Bean
- Spring calls the setBeanName() method of the bean to pass in the id value of the current bean (associate the id value of the bean with the current object)
- Spring calls the setBeanFactory() method to pass the current bean object into the current factory instance for management.
- Spring calls the setApplicationContext() method to pass the current factory into the current ApplicationContext instance for management
- Call the pre initialization method of BeanPostProcessor, and use postprocessbeforeinitialization() to process the Bean (pre enhancement)
- Call the afterpropertieset() method. It is executed when initializing beans, and can be configured for a specific bean.
- Call the customized initialization method, init method () in the bean tag
- Call the post initialization method of BeanPostProcessor (post enhancement)
- If the scope of the bean is specified as scope = "singleton" in the bean tag, putting the bean into the cache pool of Spring IOC will trigger Spring's life cycle management of the bean; If the scope of the bean is specified as scope = "prototype" in the bean tag, the bean will be handed over to the caller, who will manage the life cycle of the bean, and Spring will no longer manage the bean.
- If the Bean implements the DisposableBean interface, Spring will call the destroy () method to destroy the Bean in Spring; If the destruction method of the Bean is specified in the configuration file through the destruction method attribute, Spring will call this method to destroy the Bean.
3. DI dependency injection
There are two main methods: one is to call the set method of attribute assignment; The other uses the construction method to assign values
ref is used for object types and value is used for non object types
3.1 set injection value
When the container assigns a value to an attribute, the set method is called by default
3.1.1 basic attribute type injection value
<property name="Attribute name" value="Basic attribute value" />
3.1.2 reference attribute type injection value
<property name="Attribute name" ref="Reference object" />
3.2 structural injection
3.2.1 the value can be assigned according to the parameter name through the name attribute
<bean name="person" class="com.wjb.bean.Person"> <constructor-arg name="name" value="zhangsan"/> <constructor-arg name="car" ref="car"/> </bean>
3.2.2 you can use the index attribute to inject data according to the parameter index
<bean name="person" class="com.wjb.bean.Person"> <constructor-arg index="0" value="zhangsan"/> <constructor-arg index="1" ref="car"/> </bean>
3.2.3 using type injection
3.3 spel spring expression
<bean name="car" class="com.wjb.bean.Car" > <property name="name" value="Maybach " /> <property name="color" value="white"/> </bean> <!--utilize spel introduce car Properties of --> <bean name="person1" class="com.wjb.bean.Person" p:car-ref="car"> <property name="car" value="#{car.name}"/> <property name="name" value="zhangsan"/> </bean>
p namespace injection value (namespace p needs to be added)
Use the p: attribute name to complete the injection and use the set method
- Basic type value: p: attribute name = "value"
- Reference type value: P: attribute name - ref = "bean name"
Implementation steps: add namespace p in the configuration file
<bean id="u1" class="com.wjb.bean.User" p:age="30" p:name="Li Si" p:student- ref="stu1"></bean>
3.5 complex type injection
<!-- Array variable injection --> <property name="arrs"> <list> <value>Array 1</value> <!--Introduce other types--> <ref bean="car"/> </list> </property> <!-- Set variable assignment--> <property name="list"> <list> <value>Set 1</value> <!--The set variable contains a set--> <list> <value>Set 1 in set</value> <value>Set 2 in set</value> <value>Set 3 in set</value> </list> <ref bean="car" /> </list> </property> <!--set assignment--> <property name="set"> <set> <value>set1</value> <value>set2</value> <value>set3</value> <ref bean="u1"></ref> </set> </property> <!--map assignment --> <property name="map"> <map> <entry key="car" value-ref="car" /> <entry key="name" value="Porsche" /> <entry key="age" value="11"/> </map> </property> <!-- properties assignment --> <property name="properties"> <props> <prop key="name">pro1</prop> <prop key="age">111</prop> </props> </property>
3.6 automatic injection (the attribute is automatically assigned by the program)
autowire
- no do not auto assemble (default)
- byName attribute name = id name, call set method to assign value
- The type of byType attribute is the same as that of id object. When multiple objects of the same type are found, an error is reported, and the set method is called for assignment
- The parameter type of the constructor construction method is the same as that of the id object. If it is not found, an error will be reported. Call construction method assignment
4. Implement IOC with annotation
- Add constraints to the configuration file
xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
- Configure annotation scanning: specify the annotations in all classes under the scanning package. When scanning the package, all child packages of the package will be scanned
<!--Scan package settings--> <context:component-scan base-package="com.xzk.spring.bean" </context:component- scan>
- annotation
3.1 add above class name
@Component("object name")
@Service("person") / / service layer
@Controller("person") / / controller layer
@Repository("person") / / dao layer
@Scope(scopeName = "Singleton") / / singleton object
@Scope(scopeName = "prototype") / / multiple objects
3.2 add to attribute
@Value("property value") private String name; Add default values to attributes
@Autowired refers to automatic injection. byType is used by default (but if an interface type has two implementation classes, an error is reported). You can use @ Qualifier("bean name")
@Resource is equivalent to @ Resource(name = "object name") = = @ Autowired + @Qualifier("name")
3.3 add to method
@PostConstruct / / equivalent to init method attribute
@PreDestroy / / equivalent to destroy method attribute
5.AOP introduction
AOP (Aspect Oriented Programming) is Aspect Oriented Programming. That is to add new functions to the code without changing the source program. It is mainly used in authority authentication, log and transaction.
The function of AOP is to separate various concerns in the system and separate the core concerns from the crosscutting concerns.
6. Implementation mechanism of AOP
- Dynamic proxy of JDK: generate proxy for classes that implement interfaces. Implement InvocationHandler interface
- Dynamic proxy of CGlib: generate proxy for classes that do not implement the interface. The underlying bytecode enhancement technology is applied to generate subclass objects of the current class and implement the MethodInterceptor interface
6.1 implementation of JDK dynamic agent
- Create interfaces and corresponding implementation classes
public interface UserDao { public void test(); }
public class UserDaoImpl implements UserDao { @Override public void test() { System.out.println("test JDK Dynamic agent"); } }
- Create a proxy class to implement the invocationHandler interface
public class Dai implements InvocationHandler { private UserDao userDao; public Dai(UserDao userDao) { this.userDao = userDao; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Log start--"); //Call real method Object invoke = method.invoke(userDao, args); System.out.println("End of log--"); return invoke; } }
- test
public class Test1 { public static void main(String[] args) { //Create real objects UserDao userDao = new UserDaoImpl(); Dai dai = new Dai(userDao); //Create proxy object UserDao o = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), dai); //Executing methods through proxy objects o.test(); } }
6.2 CGlib implementation agent
CGLib uses the underlying bytecode technology to create a subclass for a class. In the subclass, the method interception technology is used to intercept the calls of all parent class methods and weave them into the crosscutting logic
Implementation steps:
- Add dependent package
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.5</version> </dependency>
- Create a normal class
public class User { public void test(){ System.out.println("test Cglib Dynamic agent"); } }
- Create CGlib agent
public class CgLib implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("Log start--cglib"); Object o1 = methodProxy.invokeSuper(o, objects); System.out.println("End of log--cglib"); return o1; } }
- test
public class Test2 { public static void main(String[] args) { //Create real objects User user = new User(); //Create proxy object Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(user.getClass()); enhancer.setCallback(new Cglib()); User o = (User) enhancer.create(); o.test(); } }
6.3 differences between the two agency methods:
- JDK dynamic proxy is a proxy generated for classes that implement interfaces. CGlib dynamic proxy: a proxy is generated for classes that do not implement interfaces. The underlying bytecode enhancement technology is applied to generate subclass objects of the current class.
- CGlib dynamic proxies cannot handle methods decorated with the final keyword.
- jdk uses reflection mechanism to call the methods of delegate class, and cglib directly calls the methods of delegate class in the way of similar index;
7. Using aop in spring
- Add the required jar package
<dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.0.8.RELEASE</version> </dependency>
- Create an enhanced class (essentially a normal class)
- Top note enhancement: before calling the target method, aop:before is called.
- Post enhancement: (if an exception does not occur), call aop:after-returning after the target method is running. Base note:
- Surround enhancement: (it will still be called if there is an exception) aop:around is called before and after the target method; You need to use ProceedingJoinPoint as a parameter (obtain the pointcut information through ProceedingJoinPoint, and use joinpoint. Processed() to call the target method)
- Exception enhancement: execute when the program has an exception (requirement: do not handle exceptions in the program code) AOP: after throwing
- Final enhancement: (no exception is called): call aop:after after the target method is running.
- aop namespace needs to be added
xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
- Set profile
<!--Create enhanced class object--> <bean id="myaop" class="com.wjb.util.MyAop"></bean> <aop:config> <!--Set the tangent point and set the method as the tangent point--> <aop:pointcut id="mypc" expression="execution(public void com.wjb.service.impl.UserServiceImpl.test())"/> <aop:aspect ref="myaop"> <!--Set pre enhancement--> <aop:before method="before" pointcut-ref="mypc"></aop:before> <!--Post enhancement--> <aop:after-returning method="after" pointcut-ref="mypc"></aop:after-returning> <!--Surround enhancement--> <aop:around method="around" pointcut-ref="mypc"></aop:around> <!--Abnormal enhancement--> <aop:after-throwing method="ex" pointcut-ref="mypc"></aop:after-throwing> <!--Final enhancement--> <aop:after method="aftera" pointcut-ref="mypc"></aop:after> </aop:aspect> </aop:config>
8. Definition of entry point method
Example of expression matching rule:
public * addUser(com.pb.entity.User): "*"Represents a return value that matches all types
public void *(com.pb.entity.User): "*"Indicates that all method names match.
public void addUser (..): ".."Indicates the number and type of all parameters matched.
* com.pb.service.*.*(..): matching com.pb.service All methods of all classes under the package.
* com.pb.service..*(..): matching com.pb.service All methods of all classes under package and sub package
9. How to obtain entry point information
Get information through JoinPoint object
- Pointcut object: joinpoint getTarget(). getClass(). getSimpleName()
- Pointcut method: joinpoint getSignature()
- Pointcut parameter: joinpoint getArgs()[0]
10. special pre enhancement – >advisor pre enhancement implementation steps
- Create an enhanced class that implements the MethodBeforeAdvice interface
- Modify ApplicationContext XML file
(1) Create enhanced class object
(2) Define the relationship between enhancements and pointcuts
<bean id="beforeAop" class="com.wjb.util.BeforeAop"></bean> <aop:config> <!--Set the tangent point and set the method as the tangent point--> <aop:pointcut id="mypc" expression="execution(public void com.wjb.service..*(..))"/> <aop:advisor advice-ref="beforeAop" pointcut-ref="mypc"> </aop:advisor> </aop:config>
11. Developed with AspectJ dependency annotation
- Add the jar packages required for AspectJ and Aop
<dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.0.8.RELEASE</version> </dependency>
- You need to add the spring annotation scanning package in the configuration file and the annotation method to start AspectJ
<!--Spring: Annotation scan package--> <context:component-scan base-package="com.wjb"></context:component-scan> <!--start-up aspectJ Annotation method of--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
-
The @ Component class needs to be enhanced by instantiating the @ Component class
-
Define the tangent point method, and use @ Pointcut to indicate the tangent point method
5.@Before(@Pointcut modified method name) indicates pre enhancement
@AfterReturning(@Pointcut modified method name) indicates post enhancement
@Around(@Pointcut modified method name) indicates surround enhancement
@AfterThrowing(@Pointcut decorated method name) indicates exception enhancement
@After(@Pointcut decorated method name) indicates the final enhancement
@Component //create object @Aspect //Indicates that it is an enhanced class public class MyAop { //Point of tangency @Pointcut("execution(* com.wjb.service.*.*(..))") public void abc(){} @Before("abc()") public void before(){ System.out.println("Pre enhancement"); } @AfterReturning("abc()") public void aftera(){ System.out.println("Post enhancement"); } @Around("abc()") public void around(ProceedingJoinPoint joinPoint){ System.out.println("Surround start"); try { joinPoint.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); } System.out.println("End of surround"); } @AfterThrowing("abc()") public void myex(){ System.out.println("Abnormal enhancement"); } @After("abc()") public void after(){ System.out.println("Final enhancement"); } }
11.1 enhancement sequence through annotation
There are two situations:
- There are exceptions: surround start - pre enhancement - (code exception) - surround end - Final enhancement - exception enhancement
- There are no exceptions: surround start - pre enhancement - surround end - Final enhancement - post enhancement
12. Spring JDBC data access
12.1 using spring JDBC to operate database
Operating database in Spring is mainly realized through jdbcTemplate object
example
Add the corresponding jar package
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.8.RELEASE</version> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> </dependencies>
public class Test { public static void main(String[] args) throws Exception { //Create c3p0 connection pool ComboPooledDataSource db = new ComboPooledDataSource(); db.setDriverClass("com.mysql.jdbc.Driver"); db.setJdbcUrl("jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8"); db.setUser("root"); db.setPassword(""); //Create a JdbcTemplate object JdbcTemplate jdbcTemplate = new JdbcTemplate(db); int update = jdbcTemplate.update("insert into student (id,stuname,sex) values (null,'Wang Wu','male')"); System.out.println("Added successfully! i="+update); } }
12.2. Spring management JdbcTemplate
Let the implementation class inherit the JdbcDaoSupport class, get the JdbcTemplate object through the getJdbcTemplate() method, and inject the data source into the implementation class through the configuration file.
//Get the information of connecting to the database through the properties file <context:property-placeholder location="classpath:db.properties"></context:property-placeholder> <bean id="db" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${driver}"></property> <property name="jdbcUrl" value="${url}"></property> <property name="user" value="${uname}"></property> <property name="password" value="${password}"></property> </bean> //Add the data source as an attribute in the implementation class <bean id="studentDao" class="com.wjb.dao.impl.StudentDaoImpl"> <property name="dataSource" ref="db"></property> </bean>
public class StudentDaoImpl extends JdbcDaoSupport implements StudentDao { @Override public int insertStudent(Student student) { String sql = "insert into student (id,stuname,sex) value (?,?,?)"; int update = getJdbcTemplate().update(sql, student.getId(),student.getStuName(), student.getSex()); return update; } }
12.3 crud
Common methods of JdbcTemplate:
JdbcTemplate.update: mainly used for addition, deletion and modification
jdbcTemplate.queryForObject: used to query single line data. There are many parameter types that need to be determined according to actual requirements
jdbcTemplate.query: used to query all data
The data obtained from the query is stored in the Result by RowWapper, and the Result can be parsed into entity class objects