Introduction of the Spring
Spring is an open source framework that is a layered JavaEE one-stop framework.
The one-stop framework means that Spring has every layer of solutions that JavaEE develops.
- The WEB tier: for SpringMVC
- Service layer: Spring’s Bean management, declarative transactions
- DAO layer: Spring’s JDBC template, ORM template
Advantages:
- IOC: Easy to decouple
- AOP: Extend the program
- Lightweight framework
- Easy integration with other frameworks
Spring source code
Spring use
The directory for decompressing the Spring development package is as follows:
- Docs: Spring development specification and API
- Libs: Spring JAR package and source code
- Schema: Constraints on the Spring configuration file
Inversion of Control (IOC)
Inversion of Control refers to an Inversion of creation rights for an object to Spring.
Use IOC will need to import the IOC related packages, the core of the above several packages in the container: beans, the context, the core, expression of four packages.
Basic concept
In Java development, Ioc means handing your designed objects over to the container for control, rather than the traditional direct control within your objects.
In traditional Java SE programming, we create objects directly inside the object through new, and the program actively creates dependent objects. IoC, on the other hand, has a container to create these objects, that is, the IoC container controls object creation.
In traditional applications, we have our own active control in the object to get the dependent object directly, that is, forward transformation; 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.
Realize the principle of
The traditional way to create an object:
UserDAO userDAO=new UserDAO();
Copy the code
Further interface oriented programming can be polymorphic:
UserDAO userDAO=new UserDAOImpl();
Copy the code
The disadvantage of this approach is that the interface and implementation class are highly coupled, and the source code needs to be modified when switching the underlying implementation class. The program design should meet the OCP primitive, and expand the program without modifying the program source code as far as possible. At this point, you can use factory mode:
class BeanFactory{
public static UserDAO getUserDAO(a){
return newUserDAOImpl(); }}Copy the code
In this way there is no coupling between the interface and the implementation class, but there is coupling between the interface and the factory.
Decoupling is achieved using a factory + reflection + configuration file approach, which is also the underlying implementation of the Spring framework IOC.
// XML configuration file
//<bean id="userDAO" class="xxx.UserDAOImpl"></bean>
class BeanFactory{
public static Object getBean(String id){
/ / to parse the XML
/ / reflection
Class clazz=Class.forName();
returnclazz.newInstance(); }}Copy the code
The IOC XML development
The xSD-configuration. HMTL file is included in the docs file. Beans Schema is defined.
<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 bean <bean id= here"userService" class="x.y.UserServiceImpl">
</bean>
</beans>
Copy the code
Call the class:
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService)applicationContext.getBean("userService");
userService.save();
Copy the code
The IOC and DI
DI refers to dependency injection, which requires an IOC environment. Spring manages this class by injecting the properties of the class’s dependencies.
For example, in userServiceImp.java:
public class UserServiceImpl implements UserService{
private String name;
public void setName(String name){
this.name=name;
}
public void save(a){
System.out.println("save "+name); }}Copy the code
In the configuration file:
<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="userService" class="spring.demo1.UserServiceImpl">
<! -- Configure dependent properties -->
<property name="name" value="tony"/>
</bean>
</beans>
Copy the code
Test code:
@Test
public void demo2(a){
// Create a Spring factory
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService)applicationContext.getBean("userService");
userService.save();
}
Copy the code
Running results:
save tony
Copy the code
As you can see, the properties configured in the configuration file have their dependent properties successfully set when Spring manages the class. If you don’t use dependency injection, you can’t use the interface, you have to use the implementation class to set it up, because the interface doesn’t have this property.
Spring’s factory class
- BeanFactory: Old version of the factory class, in the call
getBean()
Method, an instance of the class is generated. - ApplicationContext: All spring-managed classes are instantiated when the configuration file is loaded. There are two implementation classes:
- ClassPathXmlApplicationContext: load the classpath configuration file
- FileSystemXmlApplicationContext: under loading disk configuration file
Bean label configuration
- Id: unique constraint that cannot contain special characters
- Name: Theoretically repeatable, but preferably not in development. Special characters can appear
Life cycle:
- Init-method: The method executed when the bean is initialized
- Destroy-method: The method executed when the bean is destroyed
Scope of action:
- Scope: The scope of a bean. There are several types of scope, the first two are commonly used
- Singleton: Created using singleton mode by default
- Prototype: more cases
- Request: In a Web project, spring creates a class and stores it in the Request scope
- Session: In a Web project, spring creates classes and stores them in the Session scope
- Globalsession: Must be used in a portlet environment in a Web project
Property injection Settings
- Constructor – style property injection: The Car class has two properties in the constructor, name and price.
<bean id="car" class="demo.Car">
<constructor-arg name="name" value="bmw">
<constructor-arg name="price" value="123">
</bean>
Copy the code
- Set method property injection: The Employee class has two set methods, one for the common type name and the other for the reference type Car (with ref pointing to the id or name of the reference type).
<bean id="employee" class="demo.Employee">
<property name="name" value="xiaoming">
<property name="car" ref="car">
</bean>
Copy the code
- Attribute injection for the P namespace: first we need to introduce the P namespace:
<beans xmlns="http://www.springframework.org/schema/beans"/ / introductionpThe namespacexmlns:p="http://www.springframework.org/schema/p"
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>
Copy the code
If it is a common property:
<bean id="car" class="demo.Car" p:name="bmv" p:price="123">
</bean>
Copy the code
If it is a reference type:
<bean id="employee" class="demo.Employee" p:name="xiaoming" p:car-ref:"car">
</bean>
Copy the code
- SpEL(Spring Expression Language) Property injection (Spring 3.x later)
<bean id="car" class="demo.Car">
<property name="name" value="#{'xiaoming'}">
<property name="car" ref="#{car}">
</bean>
Copy the code
- Collection type attribute injection:
<bean id="car" class="demo.Car">
<property name="namelist">
<list>
<value>qirui</value>
<value>baoma</value>
<value>benchi</value>
</list>
</property>
</bean>
Copy the code
Multi-module development configuration
- When loading a configuration file, load multiple configuration files
- To introduce multiple configuration files in a configuration file by implementing
IOC annotation development
The sample
- Introducing JAR packages: In addition to the four packages described above, you will also need to introduce an AOP package.
- Create ApplicationContext.xml and use annotation development to introduce context constraints (xsD-configuration.html)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<! -- bean definitions here -->
</beans>
Copy the code
- Component scanning: Developed using IOC annotations, component scanning needs to be configured, that is, which classes under packages use IOC annotations.
<context:component-scan base-package="demo1">
Copy the code
-
Add annotations to the class
-
Use annotations to set the value of the property
Property If there is a set method, add the annotation injected by the property to the set method
Attribute has no set method. Add annotations to the attribute.
@Component("UserDao")// A
is configured with the id of UserDao and the corresponding class as UserDao
public class UserDAOImpl implements UserDAO {
@Override
public void save(a) {
// TODO Auto-generated method stub
System.out.println("save"); }}Copy the code
Annotations,
1.@Component
Component annotations, used to modify a class that Spring manages.
There are three derived annotations that perform similar functions and also modify classes.
- Controller: Decorates the Web layer class
- @service: Decorates the Service layer class
- @repository: Decorates dao layer classes
Property injection
- Common properties use @value to set the Value of the property
- Object attributes use @AutoWired, which is an annotation for property injection by type. If you want to inject properties based on the bean name or ID, you need to use @Autowired in conjunction with @Qualifier
- In real development, @resource (name=” “) is used to complete property injection by object name
3. Other notes
- @postconstruct is equivalent to init-method and is used to initialize annotations to functions
- @predestroy is equivalent to destroy-method and is used to destroy the annotation of the function
- @scope (“prototype”) @scope (“prototype”)
Comparison of XML and annotation development for IOC
- Application scenario: XML is suitable for any scenario; Annotations are only appropriate for classes that you write, not for classes that you do not provide.
- You can use XML management beans, using annotations for property injection
Comparison between IOC and traditional methods
- How to get objects: Traditionally, an object is actively created using the new keyword. In IOC mode, the object lifecycle is managed by Spring and objects are obtained directly from Spring. That is, inversion of control ———— takes control out of your hands and gives it to Spring.
AOP development
AOP is the abbreviation of Aspect Oriented Programming, which means section-oriented Programming. It is a kind of technology that realizes unified maintenance of program functions through pre-compilation and run-time dynamic proxy, and it is an extension of OOP.
AOP can enhance the program, without modifying the source code, permission verification, logging, performance monitoring, transaction control, and so on.
In other words, functions are divided into two categories, one is core business functions, and the other is auxiliary enhancement functions. The two classes of functionality are developed independently of each other. For example, the login function is a core business function, and the logging function is a secondary enhancement function. If necessary, log and login can be compiled together. Auxiliary functions are called facets, and this selective, low-coupling approach to programming that combines facets with core business functions is called facets programming.
The purpose of the AOP
DRY: Dont Repeat Yourself SoC: Sepration of Concerns
- Horizontal separation: Display layer -> Services Layer -> Persistence layer
- Vertical separation: module division
- Sectioning: Separating functional and non-functional requirements
Why use AOP
- Focus on one concern/crosscutting logic
- Easy to add/remove concerns
- Less intrusive, improved code readability and maintainability
Mainly used in permission control, cache control, transaction control, audit log, performance monitoring, distributed tracing, exception handling and so on.
The underlying implementation
JDK dynamic proxies can only generate proxies for classes that implement interfaces. Cglib dynamic proxies can generate proxy objects for classes that do not implement interfaces, generating subclass objects.
JDK dynamic proxy
JDK dynamic proxies are implemented based on interfaces, underlying reflection.
public interface Subject {
public void request(a);
}
Copy the code
Implementation class:
public class RealSubject implements Subject {
@Override
public void request(a) {
System.out.println("real subject request"); }}Copy the code
The JDK agent:
public class JdkProxySubject implements InvocationHandler {
private RealSubject realSubject;
public JdkProxySubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object result = null;
try {
result = method.invoke(realSubject, args);
} catch (Exception e) {
throw e;
} finally {
System.out.println("after");
}
returnresult; }}Copy the code
The test class
public class Client {
public static void main(String[] args) {
RealSubject rs=new RealSubject();
InvocationHandler handler=newJdkProxySubject(rs); Subject subject=(Subject) Proxy.newProxyInstance(rs.getClass().getClassLoader(),rs.getClass().getInterfaces(),handler); subject.request(); }}Copy the code
Running results:
before
real subject request
after
Copy the code
In the Client, the Proxy object is generated by calling proxy.newProxyInstance (). The parameters are classLoader, the interface to be proxied, and the InvocationHandler for the Proxy object. When subject.request() is called, the invoke method in JdkProxySubject is actually called.
Cglib
Cglib is a third-party open source generation library that dynamically adds class properties and methods.
JDK proxies are implemented based on interfaces, while Cglib is implemented based on inheritance:
public class Hello {
public void hello(String str){
System.out.println("hello "+str); }}Copy the code
This class does not implement any interface. The CGLIB proxy implements this: First, a MethodInterceptor is implemented, and method calls are forwarded to the Intercept () method of that class. The proxy object is then retrieved through the CGLIB dynamic proxy when the class is needed.
class MyMethodInterceptor implements MethodInterceptor{...@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
logger.info("You said: " + Arrays.toString(args));
returnproxy.invokeSuper(obj, args); }}Copy the code
public class Test {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(HelloConcrete.class);
enhancer.setCallback(new MyMethodInterceptor());
HelloConcrete hello = (HelloConcrete)enhancer.create();
System.out.println(hello.sayHello("I love you!")); }}Copy the code
Through additional Enhancer to specify a target, the actual processing of the agency to logical object, finally through a call to the create () method to get a proxy object, the object of all the final method call will be forwarded to MethodInterceptor. Intercept () method.
Both are
When to use JDK or CGLiB?
- If the target object implements an interface, the JDK’s dynamic proxy implementation of AOP is used by default.
- You can force CGLIB to implement AOP if the target object implements an interface.
- If the target object does not implement an interface and must use the CGLIB library, Spring automatically converts between JDK dynamic proxies and CGLIB.
How does Spring choose to use JDK or CGLiB?
- Spring uses the JDK’s dynamic proxy when the Bean implements the interface.
- Spring uses CGlib as an implementation when the Bean does not implement the interface.
- You can force the use of CGlib (add < AOP: Aspectj-autoproxy proxy-target-class=”true”/> in your Spring configuration).
AOP development in Spring (AspectJ’s XML approach)
AspectJ is an AOP framework. Spring introduces AspectJ and implements AOP development based on AspectJ.
Related terms
- Joinpoint: a Joinpoint that can be intercepted. The point at which a program is allowed to insert an aspect at runtime. This can be a function, a package path, a class, or an exception thrown
- Pointcut: Pointcut, used to specify the range of join points, which are actually intercepted, and which methods are actually enhanced
- Advice: defines the operations of the aspect near the pointcut, i.e. when and what to do. Before, after, etc.
- Aspect: an aggregation of aspects, pointcuts, and advice, typically a class abstracted from common logic across many classes that define when, where, and what to do.
- Introduction: Class level enhancement.
- Target: the object (class) to be enhanced, that is, the object to be textured into.
- Weaving: Weaving is the process of applying a cut surface to the connecting points of the cut. The section is woven into the target object at the specified join point.
- Proxy: a Proxy object that is enhanced.
Method of use
- Importing related packages
- Importing a 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"
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <! -- bean definitions here -->
</beans>
Copy the code
- Write the target class and configure:
public class ProductDaoImpl implements ProductDao {
@Override
public void save(a) {
System.out.println("save");
}
@Override
public void update(a) {
System.out.println("update");
}
@Override
public void find(a) {
System.out.println("find");
}
@Override
public void delete(a) {
System.out.println("delete"); }}Copy the code
<bean id="productDao" class="demo1.ProductDaoImpl"></bean>
Copy the code
- Write aspect classes, presumably for permission validation and configuration
public class MyAspectXML {
public void checkPri(a){
System.out.println("check auth"); }}Copy the code
<bean id="myAspect" class="demo1.MyAspectXML"></bean>
Copy the code
- Enhancements to the target classes are accomplished through an AOP configuration
<aop:config>
<aop:pointcut expression="execution(* demo1.ProductDaoImpl.save(..) )" id="pointcut1"/>
<aop:aspect ref="myAspect">
<aop:before method="chechPri" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
Copy the code
Notification type
- Pre-notification: Action before the target method executes to obtain pointcut information
<aop:before method="chechPri" pointcut-ref="pointcut1"/>
Copy the code
public void checkPri(JoinPoint joinPoint){
System.out.println("check auth "+joinPoint);
}
Copy the code
- Post notification: After the target method is executed, the method return value can be obtained
<aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result"/>
Copy the code
public void writeLog(Object result){
System.out.println("writeLog "+result);
}
Copy the code
- Circular notification: Actions before and after target method execution can prevent target method execution
<aop:around method="around" pointcut-ref="pointcut3"/>
Copy the code
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("before");
Object result=joinPoint.proceed();
System.out.println("after");
return result;
}
Copy the code
- Exception throw notification: Action when an exception occurs in the program
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex"/>
Copy the code
public void afterThrowing(Throwable ex){
System.out.println("exception "+ex.getMessage());
}
Copy the code
- Final notification: equivalent to a finally block that executes regardless of whether the code has an exception
<aop:after method="finallyFunc" pointcut-ref="pointcut4"/>
Copy the code
public void finallyFunc(a){
System.out.println("finally");
}
Copy the code
- Referral notices: not often used
Spring pointcut expression
Done based on the execution function
Syntax: The package name returned by the access modifier method. Class name. Method name (parameter)
Any field can use * instead of any value
Spring’s AOP is developed based on AspectJ annotations
Development steps
- The introduction of the jar package
- Setting up the 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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>
Copy the code
- Write the configuration target class
<bean id="orderDao" class="demo1.OrderDao"></bean>
Copy the code
public class OrderDao {
public void save(a){
System.out.println("save order");
}
public void update(a){
System.out.println("update order");
}
public void delete(a){
System.out.println("delete order");
}
public void find(a){
System.out.println("find order"); }}Copy the code
- Enable aop annotation automatic proxy
<aop:aspectj-autoproxy/>
Copy the code
- Write the aspect class and configure it
@Aspect
public class MyAspectAnno {
@Before(value="execution(* demo1.OrderDao.save(..) )")
public void before(a){
System.out.println("before"); }}Copy the code
<bean id="myAspect" class="demo1.MyAspectAnno">
Copy the code
Annotation type
Notes fall into three main categories:
- @aspect: indicates that this is a section class
- @pointcut: Represents a Pointcut, which is a class or method that needs to be enhanced
This annotation needs to be composed with a section expression. A section expression is made up of three parts: designators, wildcards, and operators.
Indicators are divided into:
- Match method: Execution ()
Execution ([modifier-pattern]// ret-type-pattern// Return type [modifier-pattern]// Package name-pattern(param-pattern)// Method name [throws exception declaration]Copy the code
- Matching annotations: @target(),@args(),@within(),@annotation()
- Matching package/class: Within ()
@Pointcut("within(demo.service.*)")
public void pointcut(a){}
Copy the code
- Match objects: this(),bean(),target()
- Matching parameter: args()
// Matches any method that takes only one Long argument
@Pointcut("args(Long)")
// Matches methods whose first argument is Long
@Pointcut("args(Long,..) ")
Copy the code
The wildcards are:
-
- Matches any number of characters
-
- Matches the specified class and its child columns
- . Use to match any number of subpackages or parameters
Operators are mainly &&, | |,! That is, and or not three.
- Advice: When should an enhanced approach be implemented
- @before: Pre-notification
- @afterreturning: Post notification
@AfterReturning(value="execution(* demo1.OrderDao.save(..) )",returning="result")
public void after(Object result){
System.out.println("after "+result);
}
Copy the code
- @around: Circular notification
@Around(value="execution(* demo1.OrderDao.save(..) )")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("before");
Object obj=joinPoint.proceed();
System.out.println("after");
return obj;
}
Copy the code
- @afterThrowing: Throws an exception
@AfterThrowing(value="execution(* demo1.OrderDao.save(..) )",throwing="e")
public void afterThrowing(Throwable e){
System.out.println("exception:"+e.getMessage();
}
Copy the code
- @after: Final notice
@After(value="execution(* demo1.OrderDao.save(..) )")
public void after(a){
System.out.println("finally");
}
Copy the code
- PointCut: PointCut annotations
@PointCut(value="execution(* demo1.OrderDao.save(..) )")
private void pointcut1(a){}
Copy the code
The advantage of annotations is that you only need to maintain pointcuts, rather than modify each annotation as you modify it.
Spring’s JDBC template
Spring also provides solutions for the persistence layer, namely ORM modules and JDBC templates. For JDBC, provides the org. Springframework. JDBC. Core. The JdbcTemplate as template class.
Using JDBC Templates
- Introduce JAR packages, database drivers, and Spring jDBC-related packages.
- Basic use:
public void demo1(a){
// Create a connection pool
DriverManagerDataSource dataSource=new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring4");
dataSource.setUsername("root");
dataSource.setPassword("123456");
// Create a JDBC template
JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
jdbcTemplate.update("insert into account values (null,? ,?) "."xiaoming".1000d);
}
Copy the code
- Hand over connection pooling and templates to Spring for management
- Configuration file:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource;">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring4"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate;">
<property name="dataSource" ref="dataSource"></property>
</bean>
Copy the code
- Test file:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcDemo2 {
@Resource(name="jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Test
public void demo2(a){
jdbcTemplate.update("insert into account values (null,? ,?) "."xiaolan".1000d); }}Copy the code
Use open source database connection pools
- Configuration using DBCP:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="JDBC: mysql: / / 192.168.66.128 spring4"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
Copy the code
- Using C3P0 configuration:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="JDBC: mysql: / / 192.168.66.128 spring4"></property>
<property name="user" value="root"></property>
<property name="password" value="123456"></property>
</bean>
Copy the code
- Import external properties files
Create the external properties file first:
JDBC. DriverClass = com. Mysql, JDBC Driver. JDBC url = JDBC: mysql: / / 192.168.66.128 spring4 JDBC username = root jdbc.password=123456Copy the code
Then configure the properties file:
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
Copy the code
CRUD operations
Insert, UPDATE, and DELETE statements all operate with the help of the template’s UPDATE method.
public void demo(a){
jdbcTemplate.update("insert into account values (null,? ,?) "."xiaoda".1000d);
jdbcTemplate.update("update account set name=? ,money=? where id=?"."xiaoda".1000d,2);
jdbcTemplate.update("delete from account where id=?".6);
}
Copy the code
Query operation:
public void demo3(a){
String name=jdbcTemplate.queryForObject("select name from account where id=?",String.class,5);
long count=jdbcTemplate.queryForObject("select count(*) from account",Long.class);
}
Copy the code
Encapsulate the returned result as a class:
public void demo4(a){
Account account=jdbcTemplate.queryForObject("select * from account where id=?".new MyRowMapper(),5);
}
Copy the code
Among them:
class MyRowMapper implements RowMapper<Account>{
@Override
public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
Account account=new Account();
account.setId(rs.getInt("id"));
account.setName(rs.getString("name"));
account.setMoney(rs.getDouble("money"));
returnaccount; }}Copy the code
Spring transaction management
The transaction
A transaction is a logical set of operations in which the units that make up the operation either all succeed or all fail.
It has four characteristics:
- Atomicity: Transactions are indivisible
- Consistency: Data integrity remains consistent before and after a transaction is executed
- Isolation: The execution of a transaction should not be interrupted by other transactions
- Persistence: Data is persisted to the database once the transaction ends
Security issues arise if isolation is not considered:
- Read the questions:
- Dirty read: a transaction reads uncommitted data from another transaction
- Non-repeatable read: A transaction reads update data that has been committed by another transaction, resulting in inconsistent results for multiple queries in one transaction
- Phantom read: a transaction reads insert data already committed by another transaction, resulting in inconsistent results for multiple queries within a transaction
- Write questions:
- Lost update
Resolve read problems: Set transaction isolation level
- Read uncommitted: No Read problem can be solved
- Read COMMITTED: Indicates that Read is committed to solve dirty Read problems
- Repeatable Read: Solves the problems of dirty and unrepeatable read
- Serializable: serializes all read issues
Transaction Management API
- PlatformTransactionManager: the platform transaction manager
This is an interface, with a number of different implementation classes, such as DataSourceTransactionManager underlying use JDBC management affairs; HibernateTransactionManager underlying use Hibernate management affairs.
- TransactionDefinition: TransactionDefinition information
Used to define information about a transaction, such as isolation level, timeout information, propagation behavior, whether it is read-only, and so on
- TransactionStatus: TransactionStatus
An object used to record the state of a transaction during transaction management.
When Spring conducts transaction management, the platform transaction manager firstly performs transaction management according to the transaction definition information. In the process of transaction management, various states are generated and these state information is recorded in the object of transaction state.
Propagation behavior of transactions
The propagation behavior of transactions mainly solves the problem of Service invocation, that is, how to operate when different transactions exist in different businesses.
Spring provides seven types of transaction propagation behavior, divided into three categories:
- Ensure multiple operations are in the same transaction
- 5, PROPAGATION_REQUIRED: The B method calls A method, and if A has A transaction, uses the transaction in A and includes the operations in B in that transaction. Otherwise, create A new transaction that includes the operations in A and B. (the default)
- PROPAGATION_SUPPORTS: If A has A transaction, use A’s transaction. Otherwise, transactions are not used
- PROPAGATION_MANDATORY: If A has A transaction, use A’s transaction. Otherwise throw an exception
- Ensure that multiple operations are not in the same transaction
- PROPAGATION_REQUIRES_NEW: If there is A transaction in A, suspend it and create A new transaction that contains only its own operations. Otherwise, create a new transaction that contains only its own operations.
- 5, PROPAGATION_NOT_SUPPORTED: If A has A transaction, suspend, no transaction is used.
- PROPAGATION_NEVER: If A has A transaction, throw an exception, meaning that A transaction cannot be run.
- The nested transaction
- Execute A transaction, PROPAGATION_NESTED: If A has A transaction, execute A transaction, and set A savepoint, and execute B’s operation. If an exception occurs, you can roll back to the original state or savepoint state.
The instance
Take transfer as an example, the DAO layer of the business layer is as follows:
public interface AccountDao {
public void outMoney(String from,Double money);
public void inMoney(String to,Double money);
}
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{
@Override
public void outMoney(String from, Double money) {
this.getJdbcTemplate().update("update account set money = money - ? where name = ?",money,from);
}
@Override
public void inMoney(String to, Double money) {
this.getJdbcTemplate().update("update account set money = money + ? where name = ?",money,to); }}public interface AccountService {
public void transfer(String from,String to,Double money);
}
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void transfer(String from, String to, Double money) { accountDao.outMoney(from, money); accountDao.inMoney(to, money); }}Copy the code
Configuring classes in XML:
<bean id="accountService" class="tx.demo.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<bean id="accountDao" class="tx.demo.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
Copy the code
Transaction Management 1: Programmatic transaction management
- Configure the platform transaction manager
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
Copy the code
- Configure the transaction management template class
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
Copy the code
- Inject transaction management templates at the business layer
<bean id="accountService" class="tx.demo1.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="transactionTemplate" ref="transactionTemplate"/>
</bean>
Copy the code
- The code implements transaction management
/ / ServiceImpl class:
private TransactionTemplate transactionTemplate;
@Override
public void transfer(String from, String to, Double money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus arg0) { accountDao.outMoney(from, money); accountDao.inMoney(to, money); }}); }Copy the code
Declarative transaction management (configured implementation, AOP based)
- Declarative transaction management in XML
- Configure the transaction manager
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
Copy the code
- Configuring transaction Notification
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="transfer" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
Copy the code
- Configuring AOP Transactions
<aop:config>
<aop:pointcut expression="execution(* tx.demo2.AccountServiceImpl.*(..) )" id="pointcut1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
Copy the code
- Annotation way
- Configure the transaction manager, as above
- Note to enable transaction management:
<tx:annotation-driven transaction-manager="transactionManager"/>
Copy the code
- Add a annotation @Transactional on classes that use transactions