The Spring framework is created due to the complexity of software development. Spring uses basic JavaBeans to do things that were previously possible only by EJB. However, Spring's purpose is not limited to server-side development. From the perspective of simplicity, testability and loose coupling, most Java applications can benefit from Spring. Spring is a lightweight control inversion (IoC) and section-oriented (AOP) container framework.
◆Purpose: Solve the complexity of enterprise application development
◆Function: Use basic JavaBean instead of EJB, and provides more enterprise application functions
◆Scope: Any Java application
Inversion of Control (IoC in English abbreviation) gives the right to create objects to the framework, which is an important feature of the framework and is not a special term for object-oriented programming. It includes dependency injection and dependency lookup. In the traditional business layer, when resources are needed, new resources are found in the business layer, so that the coupling (interdependence and correlation between programs) is higher. Now hand over the new part to spring to achieve high cohesion and low coupling. In short: Originally, whenever the dao layer or service layer method was called, the app would use new, and now the new rights were handed over to spring, and what resources were needed were obtained from spring!
1. Download the dependency jar package required for the framework
The official spring website is: http://spring.io/
Download the jar package: http://repo.springsource.org/libs-release-local/org/springframework/spring
2. Import the basic jar package
In fact, the basic core jars include beans;context;core;expression packages, and the others depend on log4j logs. Of course, spring jars are more than that, they are added slowly in the later stage.
3. Configure log4j configuration file
The log file is defined in the src directory
### direct log messages to stdout ###log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.errlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n### direct messages to file mylog.log ###log4j.appender.file=org.apache.log4j.FileAppenderlog4j.appender.file.File=c/:mylog.loglog4j.appender.file.layout=org.apache.log4j.PatternLayoutlog4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n### set log levels - for more verbose logging change 'info' to 'debug' ###log4j.rootLogger=info, stdout4. Test whether the log file is deployed successfully
package com.clj.demo1;import org.apache.log4j.Logger;import org.junit.Test;/** * Demo log usage* @author Administrator * */public class Demo1 { //Create log class private Logger log=Logger.getLogger(Demo1.class); @Test public void run1(){ //Change the info in the log4j.rootLogger attribute to off, and log.info("execute"); }}5. Define an interface and implement class
interface:
package com.clj.demo2;public interface UserService { public void saysHello();}Implementation Class
package com.clj.demo2;public class UserServiceImpl implements UserService{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void init(){ System.out.println("Initialize.."); } public void saysHello() { System.out.println("Hello Spring"+"/t"+name); } public void destory() { System.out.println("Destroy.."); }}6. Define spring-specific configuration files
Define the name of applicationContext.xml, the location is src, the same directory as the log file, import the corresponding constraints, and inject the implementation class into the configuration file. Just start with the beginning, use bean constraints
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- Use bean tag 1. The id value is unique (must write) 2. Note: class is the implementation classpath, not an interface (must write) 3. Initialization work before the core method is executed (select write) 4. Initialization work after the core method is executed (select write) --> <bean id="userService" init-method="init" destroy-method="destory"> <property name="name" value="Jaxiansen"></property> </bean></beans>
7. Test
public class Demo1 { /** * Original way*/ @Test public void run(){ //Create implementation class UserServiceImpl s=new UserServiceImpl(); s.setName("Jaxiansen"); s.sayHello(); } /** * Old factory version BeanFactory * Old factory will not create configuration file objects*/ @Test public void run2(){ BeanFactory factory=new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); UserService us=(UserService)factory.getBean("userService"); us.sayHello(); } /** * Use spring framework IOC method* Create a startup server in the new version of factory to create a configuration file object, and there is no need to load the factory when calling again*/ @Test public void run3(){ //Create the factory and load the core configuration file (ClassPathXmlApplicationContext is found under src) ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); //Get the object from the factory (id value in the configuration file, polymorphism is used here) UserService usi=(UserService) ac.getBean("userService"); //Calling the object's method to execute usi.sayHello(); } /** * Demo destroy-method method* The bean destroy method will not be automatically executed* Unless it is automatically called in scope= singleton or in a web container, the main function or test case needs to be called manually (need to use the close() method of ClassPathXmlApplicationContext) */ @Test public void run4(){ //Create a factory and load the core configuration file (ClassPathXmlApplicationContext is found under src) ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); //Get the object from the factory (id value in the configuration file, polymorphism is used here) UserService usi=(UserService) ac.getBean("userService"); //Calling the object's method to execute usi.sayHello(); //ApplicationContext implementation class provides a close method, and the factory can be closed and the destory-method method can be executed. }}The difference between old factories and new factories
* Difference between BeanFactory and ApplicationContext
* BeanFactory -- BeanFactory takes lazy loading, and the bean will be initialized only when you getBean the first time
* ApplicationContext -- When loading applicationContext.xml, a specific instance of the Bean object will be created, and some other functions are provided.
* Event delivery
* Bean automatic assembly
* Context implementations of various application layers
Summary: This is the most basic demo, which configures the implementation class into the spring configuration file. Each time the server is started, the configuration file will be loaded, thereby instantiating the implementation class.
1. What is dependency injection?
Spring can effectively organize objects of J2EE application levels. Whether it is the Action object of the control layer, the Service object of the business layer, or the DAO object of the persistence layer, it can be organically coordinated and run under Spring's management. Spring organizes objects of each layer together in a loosely coupled manner. Action objects do not need to care about the specific implementation of Service objects, Service objects do not need to care about the specific implementation of persistent layer objects, and calls to each layer object are completely interface-oriented. When the system needs to be refactored, the amount of code rewrite will be greatly reduced. Dependency injection makes the bean and bean organized in configuration files, rather than being hardcoded. Understand dependency injection
Dependency Injection and Inversion of Control are the same concept. The specific meaning is: when a role (maybe a Java instance, caller) needs the assistance of another role (another Java instance, caller), in the traditional programming process, the caller is usually created by the caller. But in Spring, the work of creating the callee is no longer done by the caller, so it is called control inversion; the work of creating the callee instance is usually done by the Spring container and then injected into the caller, so it is also called dependency injection.
Whether it is dependency injection or control inversion, it means that Spring adopts a dynamic and flexible way to manage various objects. The specific implementations between objects are transparent to each other.
2. The concept of IOC and DI
* IOC -- Inverse of Control, control inversion, invert the creation right of the object to Spring! !
* DI -- Dependency Injection, Dependency Injection, when the Spring framework is responsible for creating Bean objects, dynamically injecting dependency objects into the Bean component! !
3. Demo
For class member variables, there are two common injection methods.
Property set method injection and constructor method injection
First demonstrate the first type: property set method injection
1) Persistent layer
package com.clj.demo3;public class CustomerDaoImpl { public void save(){ System.out.println("I am Dao of the persistence layer"); }}2) Business layer
Note: At this time, I want to inject the persistence layer into the business layer and hand over the right to create the persistence layer instance to the framework, the condition is that the business layer must provide the member attributes and set methods of the persistence layer.
package com.clj.demo3;/** * Dependency injection injects the dao layer into the service layer* @author Administrator * */public class CustomerServiceImpl{ //Provide member zodiac, provide set method private CustomerDaoImpl customerDao; public void setCustomerDao(CustomerDaoImpl customerDao) { this.customerDao = customerDao; } public void save(){ System.out.println("I am the service..."); //1. Original method//new CustomerDaoImpl().save(); //2.spring IOC method customerDao.save(); }}3) Configuration file configuration
<!-- Demonstration Dependency Injection--> <bean id="customerDao"/> <bean id="customerService"> <!-- Inject Dao into service layer--> <property name="customerDao" ref="customerDao"></property> </bean>
4) Test
/** * spring Dependency injection method * Inject dao layer into service layer */ @Test public void run2(){ //Create the factory, load the configuration file, and the customerService is created, thus creating customerDao ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); CustomerServiceImpl csi=(CustomerServiceImpl) context.getBean("customerService"); csi.save(); }The second type: construction method injection
1) Pojo class and provide constructor methods
package com.clj.demo4;/** * The demo injection method* @author Administrator * */public class Car1 { private String cname; private Double price; public Car1(String cname, Double price) { super(); this.cname = cname; this.price = price; } @Override public String toString() { return "Car1 [cname=" + cname + ", price=" + price + "]"; } }2) Configuration file configuration
<!-- Demonstrate the method of injection of construction method --> <bean id="car1"> <!-- Write method 1<constructor-arg name="cname" value="BMW"/> <constructor-arg name="price" value="400000"/> --> <!-- Write method 2--> <constructor-arg index="0" value="BMW"/> <constructor-arg index="1" value="400000"/> </bean>
3) Test
@Test public void run1(){ ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); Car1 car=(Car1) ac.getBean("car1"); System.out.println(car); }Extension: Constructing method injects one object into another
1) pojo class: Purpose: Inject the car in the above column into humans and make it one of the attributes. In this class, the member attributes of the car must be provided and parameterized construction methods must be provided.
package com.clj.demo4;public class Person { private String name; private Car1 car1; public Person(String name, Car1 car1) { super(); this.name = name; this.car1 = car1; } @Override public String toString() { return "Person [name=" + name + ", car1=" + car1 + "]"; }}2) Configuration file
<!-- Constructor-arg name="name" value="Jaxiansen"/> <constructor-arg name="car1" ref="car1"/> </bean>
4. How to inject a collection array
1) Define the pojo class
package com.clj.demo4;import java.util.Arrays;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.Set;/** * Demonstrate the way to set injection* @author Administrator * */public class User { private String[] arrrs; private List<String> list; private Set<String> sets; private Map<String,String> map; private Properties pro; public void setPro(Properties pro) { this.pro = pro; } public void setSets(Set<String> sets) { this.sets = sets; } public void setMap(Map<String, String> map) { this.map = map; } public void setList(List<String> list) { this.list = list; } public void setArrrs(String[] arrrs) { this.arrs = arrrs; } @Override public String toString() { return "User [arrs=" + Arrays.toString(arrs) + ", list=" + list + ", sets=" + sets + ", map=" + map + ", pro=" + pro + "]"; } }2) Configuration file
<!-- Injection set--> <bean id="user"> <!-- Array--> <property name="arrs"> <list> <value>Number1</value> <value>Number2</value> <value>Number3</value> </list> </property> <!-- list set--> <property name="list"> <list> <value>Jin Zaizhong</value> <value>Wang Jie</value> </list> </property> <!-- set set--> <property name="sets"> <set> <value>Haha</value> <value>Haha</value> </set> </property> <!-- map set--> <property name="map"> <map> <entry key="aa" value="rainbow"/> <entry key="bb" value="hellowvenus"/> </map> </property> <!-- Property file--> <property name="pro"> <props> <prop key="username">root</prop> <prop key="password">123</prop> </props> </property> </bean>
3) Test
/** * Test injection collection*/ @Test public void run3(){ ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); User user= (User) ac.getBean("user"); System.out.println(user); }5. How to develop in modules
Add the <import> tag to the main configuration file (assume that, a configuration file applicationContext2.xml is defined under the com.clj.test package)
<!-- Introducing other configuration files by module development--> <import resource="com/clj/test/applicationContext2.xml"/>
1. Getting started
1).Import jar package
In addition to the previous 6 packages, you also need a spring-aop package to play annotation.
2). Persistence layer and implementation layer (interfaces are ignored here)
Persistent layer
package com.clj.demo1;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;import org.springframework.stereotype.Repository;/** * Container management handed over by UserDaoImpl to IOC* @author Administrator * */public class UserDaoImpl implements UserDao{ @Override public void save() { System.out.println("Save the client.."); }}Business layer
package com.clj.demo1;import javax.annotation.PostConstruct;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;public class UserServiceImpl implements UserService{ @Override public void saysHello() { System.out.println("Hello spring"); }}3). Define the configuration file
At this time, the constraints need to add context constraints and add component scanning
<?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" 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 --> <!-- Open annotation scan: base-package specifies scan face package --> <context:component-scan base-package="com.clj.demo1"/></beans>
4) Add annotations to the implementation class
/** * Component annotation, which can be used to mark the current class* Similar to <bean id="userService"> * value means giving an alias for the class*/@Component(value="userService")public class UserServiceImpl implements UserService{ //Omitted}5) Write tests
/** * Annotation method*/ @Test public void run2(){ ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); UserService us=(UserService) ac.getBean("userService"); us.sayHello(); }2. About bean management common attributes
1. @Component: Component. (acted on the class) The most primitive annotation, it is OK to write this for all classes that need annotation, it is general
2. Three derivative annotations of @Component are provided in Spring: (the functions are currently consistent)
* @Controller -- Works on the WEB layer
* @Service -- Acts at the business level
* @Repository -- acting on the persistence layer
* Note: These three annotations are intended to make the purpose of the annotation class itself clear, and Spring will enhance it in subsequent versions.
3. Annotations for attribute injection (Note: When using annotation injection, you can do not need to provide a set method)
* If it is a normal type of injection, you can use the value annotation
* @Value -- for injecting normal types
* If the injected object type, use the following annotation
* @Autowired -- By default, the type is automatically assembled by type, and it has nothing to do with the class name of the injected class.
* If you want to inject by name
* @Qualifier -- Forced use of name injection must be used with Autowired, specify the class name, and related to the injected class name
* @Resource -- equivalent to @Autowired and @Qualifier
* Emphasize: Annotations provided by Java
* The attribute uses the name attribute
4. Annotation of the scope of bean
* Annotated as @Scope(value="prototype"), which is used on the class. The values are as follows:
* singleton -- singleton, default value
* prototype -- multiple cases
5. Configuration of the life cycle of the bean (understand)
* The annotation is as follows:
* @PostConstruct -- equivalent to init-method
* @PreDestroy -- equivalent to destroy-method
1. Demonstrate attribute object annotation
Condition: Inject attributes (name) and object (userDaoImpl) into the business layer by scanning.
1) Open the persistence layer to scan the annotation
//@Component(value="userDao")Universal class annotation@Repository(value="ud")public class UserDaoImpl implements UserDao{ @Override public void save() { System.out.println("Save the client.."); }}2) The business layer provides annotations for attributes and objects
package com.clj.demo1;import javax.annotation.PostConstruct;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;/** * Component annotation, can be used to mark the current class* Similar to <bean id="userService"> * value means giving an alias to the class *///@Scope(value="grototype") multiple columns (singletype is a single column) @Component(value="userService") public class UserServiceImpl implements UserService{ //Attribute annotation: It is equivalent to injecting the specified string into the name attribute. The setName method can be omitted without writing @Value(value="Jaxiansen") private String name; /** * Reference injection method 1: Autowired() * Reference injection method 2: Autowired() + Qualifier * Reference injection method 3: @Resource(name="userDao") java method, identify injection by name*/ //Autowired() is automatically assembled and injected by type (disadvantages: because it matches by type, so it is not very accurate) @Autowired() @Qualifier(value="ud") //Injection by name, it must be used with Autowired. Both can specify the class private UserDao userDao; //Note that the value in Qualifier is the annotation name on the top of the UserDaoImpl class name, or you can specify the id name of the bean in the configuration file/*public void setName(String name) { this.name = name; }*/ @Override public void saysHello() { System.out.println("Hello spring"+name); userDao.save(); } // @PostConstruct tag annotation for initialization in action lifecycle @PostConstruct public void init(){ System.out.println("Initialize..."); }}3) The configuration file only needs to be enabled to scan all the configuration files
<?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" 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 --> <!-- Open annotation scan: base-package specifies scan face package --> <context:component-scan base-package="com.clj.demo1"/></beans>
Note: As for collections, it is recommended to use configuration files
2. Spring framework integrates JUnit unit testing
1) Add the required dependency package spring-test.jar
Note: Myeclipes comes with its own Junit environment, but sometimes due to version problems, a new Junit environment may be needed. Here I have downloaded a new Junit-4.9 jar package online. If myeclipes is newer, you don't need to consider it.
2) Write a test class and add corresponding annotations
@RunWith and @ContextConfiguration (this is used to load the configuration file, because the default path from WebRoot is a first-level directory, plus this is to determine that src is a first-level directory)
package com.clj.demo2;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.clj.demo1.UserService;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo2 { @Resource(name="userService") private UserService userService; @Test public void run1(){ userService.sayHello(); }}6. AOP of spring framework
1.What is AOP
* In the software industry, AOP is the abbreviation of Aspect Oriented Programming, meaning: facet programming, functional modularity
* AOP is a programming paradigm, affiliated with the category of soft work, guiding developers how to organize program structures
* AOP was first proposed by the AOP Alliance organization and formulated a set of norms. Spring introduced AOP ideas into the framework and must abide by the AOP Alliance specifications.
* A technology to achieve unified maintenance of program functions through precompilation and dynamic agents during runtime
* AOP is a continuation of OOP, a hot topic in software development, an important part of Spring framework, and a derivative paradigm of functional programming.
* Using AOP, various parts of the business logic can be isolated, thereby reducing the coupling between the parts of the business logic, improving the reusability of the program, and improving the efficiency of development.
AOP adopts a horizontal extraction mechanism, replacing the repetitive code of the traditional vertical inheritance system (performance monitoring, transaction management, security inspection, caching)
2. Why study AOP
* The program can be enhanced without modifying the source code! ! (Create a proxy for a fixed method. Before accessing the method, enter the proxy first. In the proxy, you can write more functions to make the method more powerful and enhance the program)
Aop: Oriented programming, modularizes everything, each module is relatively independent, modules can be shared (same), and different are particularly customized. Use this instead of traditional vertical programming to improve program reusability
3. AOP implementation (implementation principle)
The implementation of Aop includes two proxy methods <1> to implement class interfaces: use JDK dynamic proxy <2> not implemented class interfaces: use CGLIB dynamic proxy
1. Implement JDK dynamic proxy
1) Define the persistence layer interface implementation class
package com.clj.demo3;public interface UserDao { public void save(); public void update();} package com.clj.demo3;public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println("Save user"); } @Override public void update() { System.out.println("Modify user"); }}2) Define JDK dynamic proxy tool class
This tool class adds some functions when executing the persistence layer save method, and in development, it is necessary to enhance a certain method without changing the source code
package com.clj.demo3;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * Generate proxy objects in JDK (demonstrate AOP principles) * @author Administrator * */public class MyProxyUtils { public static UserDao getProxy(final UserDao dao){ //Use Proxy class to generate proxy objects UserDao proxy=(UserDao)Proxy.newProxyInstance(dao.getClass().getClassLoader() , dao.getClass().getInterfaces(), new InvocationHandler() { //As soon as the proxy object is executed, the invoke method will be executed once public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //proxy represents the current proxy object//method method executed by the current object//args encapsulated parameters//Let the class save or update method execute normally if("save".equals(method.getName())){ System.out.println("Save executed"); //Open transaction} return method.invoke(dao, args); } }); return proxy; }}3) Test
package com.clj.demo3;import org.junit.Test;public class Demo1 { @Test public void run1(){ //Get the target object UserDao dao=new UserDaoImpl(); dao.save(); dao.update(); System.out.println("====================================================================================================================================================== Use the tool class to get the proxy object UserDao proxy=MyProxyUtils.getProxy(dao); //Calling the proxy object method proxy.save(); proxy.update(); }}2. Implement CGLIB technology
1) Define the persistence layer, there is no interface at this time
package com.clj.demo4;public class BookDaoImpl { public void save(){ System.out.println("Save Book"); } public void update(){ System.out.println("Modify Book"); }}2) Write tool classes
package com.clj.demo4;import java.lang.reflect.Method;import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;/** * Principle of implementation of Cglib proxy method* @author Administrator * */public class MyCglibUtils { /** * Generate proxy object using CGLIB method* @return */ public static BookDaoImpl getProxy(){ Enhancer enhancer=new Enhancer(); //Set the parent class enhancer.setSuperclass(BookDaoImpl.class); //Set the callback function enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] objs, MethodProxy methodProxy) throws Throwable { if(method.getName().equals("save")){ System.out.println("I saved"); System.out.println("Proxy object executed"); } return methodProxy.invokeSuper(obj, objs);//is the method executed} }); //generate the proxy object BookDaoImpl proxy=(BookDaoImpl) enhancer.create(); return proxy; }}3) Write test classes
package com.clj.demo4;import org.junit.Test;public class Demo1 { @Test public void run1(){ //Target object BookDaoImpl dao=new BookDaoImpl(); dao.save(); dao.update(); System.out.println("==============================); BookDaoImpl proxy=MyCglibUtils.getProxy(); proxy.save(); proxy.update(); }}3. Spring's AOP development based on AspectJ (configuration file method)
1) Deploy the environment and import the corresponding jar package
2) Create configuration files and introduce AOP constraints
<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/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
3) Create interfaces and implement classes
package com.clj.demo5;public interface CustomerDao { public void save(); public void update();} package com.clj.demo5;/** * Use configuration file to interpret AOP * @author Administrator * */public class CustomerDaoImpl implements CustomerDao { @Override public void save() { //Simulate exception//int a=10/0; System.out.println("Save the customer"); } @Override public void update() { // TODO Auto-generated method stub System.out.println("Updated the customer"); }}4) Define the facet class
package com.clj.demo5;import org.aspectj.lang.ProceedingJoinPoint;/** * Facet class: entry point + notification* @author Administrator * */public class MyAspectXml { /** * Notification (specific enhancement) */ public void log(){ System.out.println("log log"); } /** * The method is executed successfully or exceptions will be executed */ public void after(){ System.out.println("final notification"); } /** * After the method is executed, the post notification is executed. If an exception occurs in the program, the post notification will not be executed */ public void afterReturn(){ System.out.println("Post Notification"); } /** * After the method is executed, if there is an exception, the exception notification will be executed */ public void afterThrowing(){ System.out.println("Exception Notification"); } /** * Surround Notification: Notification is made before and after the method is executed. * By default, the method of the target object cannot be executed, and the target object needs to be executed manually */ public void around(ProceedingJoinPoint joinPoint){ System.out.println("Wrap Notification 1"); // Manually let the method of the target object execute try { joinPoint.proceed(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Wrap Notification 2"); }}5) Inject implementation classes and facet classes
<?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 --> <!-- Configure the customer's dao --> <bean id="customerDao"/> <!-- Configure the section class --> <bean id="myAspectXml"/> <!-- Configure the section class --> <bean id="myAspectXml"/> <!-- Configure the section class: entry point + notification (type) --> <aop:aspect ref="myAspectXml"> <!-- Configure the pre-notification, and the enhancement method will be executed before the save method is executed --> <!-- Point cutting expression: execution(public void com.clj.demo5.CustomerDaoImpl.save()) --> <!-- Point cutting expression: 1.execution() is fixed, must be written 2.public can be omitted and not written 3. The return value must be written, strictly based on the point cutting method, otherwise the enhancement method will not be executed, and it can be replaced by * to represent any return value 4. The package name must be written, and it can be replaced by * (such as: *..* (default all packages); com.clj.*) 5. The class name must be written. You can partially use * (such as *DaoImpl means a persistent layer implementation class ending with 'DaoImpl'), but it is not recommended to use * instead of the entire class name 6. The method must be written. You can partially use * (such as save* means a method starting with 'save'), but it is not recommended to use * instead of the entire class name 7. The method parameters are determined according to the actual method, and you can use '..' to indicate that there are 0 or more parameters --> <!-- <aop:before method="log" pointcut="execution(public void com.clj.*.CustomerDaoImpl.save(..))"/> --> <aop:before method="log" pointcut="execution(* *..*.*DaoImpl.save*(..))"/> </aop:aspect> </aop:config></beans>
6) Test
package com.clj.demo5;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo1 { @Resource(name="customerDao") private CustomerDao customerDao; @Test public void run(){ customerDao.save(); customerDao.update(); }}Extension: Facet class upgrade
<?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 --> <bean id="myAspectXml"/> <aop:config> <aop:aspect ref="myAspectXml"> <!-- Configure final notification<aop:after method="after" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>-- Configure post-notification<aop:after-returning method="afterReturn" pointcut="execution(* *..*.*DaoImpl.save*(..))"/>--> <!-- Configuration exception notification<aop:after-throwing method="afterThrowing" pointcut="execution(* *..*.*.DaoImpl.save*(..))"/>--> <aop:around method="around" pointcut="execution(* *..*.*.DaoImpl.update*(..))"/> </aop:aspect> </aop:config></beans>
4. Spring framework AOP annotation method
1) Create interfaces and implement classes
package com.clj.demo1;public interface CustomerDao { public void save(); public void update();} package com.clj.demo1;public class CustomerDaoImpl implements CustomerDao{ @Override public void save() { // TODO Auto-generated method stub System.out.println("Save customer.."); } @Override public void update() { // TODO Auto-generated method stub System.out.println("Update customer"); }}2) Define the facet class
package com.clj.demo1;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;/** * 注解方式的切面类* @Aspect表示定义为切面类*/@Aspectpublic class MyAspectAnno { //通知类型:@Before前置通知(切入点的表达式) @Before(value="execution(public * com.clj.demo1.CustomerDaoImpl.save())") public void log(){ System.out.println("记录日志。。"); } //引入切入点@After(value="MyAspectAnno.fun()") public void after(){ System.out.println("执行之后"); } @Around(value="MyAspectAnno.fun()") public void around(ProceedingJoinPoint joinPoint){ System.out.println("环绕通知1"); try { //让目标对象执行joinPoint.proceed(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("环绕通知2"); } //自定义切入点@Pointcut(value="execution(public * com.clj.demo1.CustomerDaoImpl.save())") public void fun(){ }}3)配置切面类和实现类,并开启自动代理
<?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"> <!-- 开启自动注解代理--> <aop:aspectj-autoproxy/> <!-- 配置目标对象--> <bean id="customerDao"/> <!-- 配置切面类--> <bean id="myAspectAnno"/></beans>
spring提供了JDBC模板:JdbcTemplate类
1.快速搭建
1)部署环境
这里在原有的jar包基础上,还要添加关乎jdbc的jar包,这里使用的是mysql驱动
2)配置内置连接池,将连接数据库程序交给框架管理,并配置Jdbc模板类
<?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"> <!-- 先配置连接池(内置) --> <bean id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置JDBC的模板类--> <bean id="jdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean></beans>
3) Test
package com.clj.demo2;import java.sql.ResultSet;import java.sql.SQLException;import java.util.List;import javax.annotation.Resource;import org.apache.commons.dbcp.BasicDataSource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.cglib.beans.BeanMap;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * 测试JDBC的模板类,使用IOC的方式* @author Administrator * */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo2 { @Resource(name="jdbcTemplate") private JdbcTemplate jdbcTemplate; /** * 插入*/ @Test public void run1(){ String sql="insert into t_account values(null,?,?)"; jdbcTemplate.update(sql,"李钇林",10000); } /** * 更新*/ @Test public void run2(){ String sql="update t_account set name=? where id=?"; jdbcTemplate.update(sql,"李钇林",1); } /** * 删除*/ @Test public void run3(){ String sql="delete from t_account where id=?"; jdbcTemplate.update(sql,4); } /** * 测试查询,通过主键来查询一条记录*/ @Test public void run4(){ String sql="select * from t_account where id=?"; Account ac=jdbcTemplate.queryForObject(sql, new BeanMapper(),1); System.out.println(ac); } /** * 查询所有*/ @Test public void run5(){ String sql="select * from t_account"; List<Account> ac=jdbcTemplate.query(sql,new BeanMapper()); System.out.println(ac); }}/** * 定义内部类(手动封装数据(一行一行封装数据,用于查询所有) * @author Administrator * */class BeanMapper implements RowMapper<Account>{ @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { Account ac=new Account(); ac.setId(rs.getInt("id")); ac.setName(rs.getString("name")); ac.setMoney(rs.getDouble("money")); return ac; } }2、配置开源连接池
一般现在企业都是用一些主流的连接池,如c3p0和dbcp
首先配置dbcp
1)导入dbcp依赖jar包
2)编写配置文件
<!-- 配置DBCP开源连接池--> <bean id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean>
将模板类中引入的内置类datasource改为开源连接池的
3)编写测试类
配置c3p0
1)导入c3p0依赖jar包
2)配置c3p0
<!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean>
将模板类中引入的内置类datasource改为开源连接池的
3)编写测试类
1、什么是事务
数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。
2、怎么解决事务安全性问题
读问题解决,设置数据库隔离级别;写问题解决可以使用悲观锁和乐观锁的方式解决
3、快速开发
方式一:调用模板类,将模板注入持久层
1)编写相对应的持久层和也外层,这里省略接口
package com.clj.demo3;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ // 方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void outMoney(String out, double money) { String sql="update t_account set money=money-? where name=?"; jdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; jdbcTemplate().update(sql,money,in); } } package com.clj.demo4;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //采用的是配置文件注入方式,必须提供set方法private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); }}2)配置相对应的配置文件
<?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"><!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean><!-- 配置JDBC的模板类--> <bean id="jdbcTemplate"> <property name="dataSource" ref="dataSource"/> </bean><!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean><bean id="accountDao"> <!-- 注入模板类--> <property name="jdbcTemplate" ref="jdbcTemplate"/> <property name="dataSource" ref="dataSource"/> </bean></beans>
3)测试类
package com.clj.demo3;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class Demo1 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //调用支付的方法accountService.pay("佳先森","李钇林",100); }}方式二:持久层继承JdbcDaoSupport接口,此接口封装了模板类jdbcTemplate
1)编写配置文件
<?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"> <!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean></beans>
2)更改持久层
package com.clj.demo3;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ //方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } //方式二:持久层继承JdbcDaoSupport,它里面封转了模板类,配置文件持久层无需注入模板类,也不需要配置模板类public void outMoney(String out, double money) { //jdbcTemplate.update(psc); String sql="update t_account set money=money-? where name=?"; this.getJdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; this.getJdbcTemplate().update(sql,money,in); } }3)更改业务层
package com.clj.demo4;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //采用的是配置文件注入方式,必须提供set方法private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); } }4)测试类和上述一样
4、spring事务管理
Spring为了简化事务管理的代码:提供了模板类TransactionTemplate,手动编程的方式来管理事务,只需要使用该模板类即可! !
1、手动编程方式事务(了解原理)
1)快速部署,搭建配置文件,配置事务管理和事务管理模板,并在持久层注入事务管理模板
配置事务管理器
<!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
配置事务管理模板
<bean id="transactionTemplate"> <property name="transactionManager" ref="transactionManager"/></bean>
将管理模板注入业务层
<bean id="accountService"> <property name="accountDao" ref="accountDao"/> <property name="transactionTemplate" ref="transactionTemplate"/></bean>
全部代码:
<?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"> <!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> <property name="transactionTemplate" ref="transactionTemplate"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 手动编码方式,提供了模板类,使用该类管理事务比较简单--> <bean id="transactionTemplate"> <property name="transactionManager" ref="transactionManager"/> </bean></beans>
2)在业务层使用模板事务管理
package com.clj.demo3;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //采用的是配置文件注入方式,必须提供set方法private AccountDao accountDao; //注入事务模板类private TransactionTemplate transactionTemplate; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } /** * 转账的方法*/ public void pay(final String out,final String in, final double money) { transactionTemplate.execute(new TransactionCallbackWithoutResult() { //事务的执行,如果没有问题,提交,如果楚翔异常,回滚protected void doInTransactionWithoutResult(TransactionStatus arg0) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); } }); }}3)测试类和上一致
package com.clj.demo4;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext2.xml")public class Demo2 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //调用支付的方法accountService.pay("佳先森","李钇林",100); }}申明式事务有两种方式:基于AspectJ的XML方式;基于AspectJ的注解方式
1、XML方式
1)配置配置文件
需要配置平台事务管理
<!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
配置事务增强
<tx:advice id="myAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 给方法设置数据库属性(隔离级别,传播行为) --> <!--propagation事务隔离级别:一般采用默认形式:tx:method可以设置多个--> <tx:method name="pay" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
aop切面类
<aop:config> <!-- aop:advisor,是spring框架提供的通知--> <aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.clj.demo4.AccountServiceImpl.pay(..))"/> </aop:config>
All codes
<?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"> <!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 申明式事务(采用XML文件的方式) --> <!-- 先配置通知--> <tx:advice id="myAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 给方法设置数据库属性(隔离级别,传播行为) --> <!--propagation事务隔离级别:一般采用默认形式:tx:method可以设置多个--> <tx:method name="pay" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 配置AOP:如果是自己编写的AOP,使用aop:aspect配置,使用的是Spring框架提供的通知--> <aop:config> <!-- aop:advisor,是spring框架提供的通知--> <aop:advisor advice-ref="myAdvice" pointcut="execution(public * com.clj.demo4.AccountServiceImpl.pay(..))"/> </aop:config> <!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean></beans>
2)编写持久层和业务层(省略接口)
package com.clj.demo5;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ //方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } //方式二:持久层继承JdbcDaoSupport,它里面封转了模板类,配置文件持久层无需注入模板类,也不需要配置模板类public void outMoney(String out, double money) { //jdbcTemplate.update(psc); String sql="update t_account set money=money-? where name=?"; this.getJdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; this.getJdbcTemplate().update(sql,money,in); } } package com.clj.demo5;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.annotation.Transactional;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;public class AccountServiceImpl implements AccountService{ //采用的是配置文件注入方式,必须提供set方法private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); } }3)测试类
package com.clj.demo4;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext2.xml")public class Demo2 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //调用支付的方法accountService.pay("佳先森","李钇林",100); }}2、注解方式
1)配置配置文件
配置事务管理
<bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
开启注释事务
<!-- 开启事务的注解--> <tx:annotation-driven transaction-manager="transactionManager"/>
All codes
<?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"> <!-- 配置C3P0开源连接池--> <bean id="dataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.174.130:3306/SSH"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 配置平台事务管理器--> <bean id="transactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 开启事务的注解--> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 配置业务层和持久层--> <bean id="accountService"> <property name="accountDao" ref="accountDao"/> </bean> <bean id="accountDao"> <property name="dataSource" ref="dataSource"/> </bean></beans>
2)业务层增加@Transactional
package com.clj.demo5;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.annotation.Transactional;import org.springframework.transaction.support.TransactionCallbackWithoutResult;import org.springframework.transaction.support.TransactionTemplate;//在当前类加此注解表示当前类所有的全部都有事务@Transactionalpublic class AccountServiceImpl implements AccountService{ //采用的是配置文件注入方式,必须提供set方法private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } @Override public void pay(String out, String in, double money) { // TODO Auto-generated method stub accountDao.outMoney(out, money); int a=10/0; accountDao.inMoney(in, money); } }3)持久层不变
package com.clj.demo5;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.support.JdbcDaoSupport;public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao{ //方式一:将jdbc模板类注入到配置文件中,直接在持久层写模板类// private JdbcTemplate jdbcTemplate;// public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {// this.jdbcTemplate = jdbcTemplate;// } //方式二:持久层继承JdbcDaoSupport,它里面封转了模板类,配置文件持久层无需注入模板类,也不需要配置模板类public void outMoney(String out, double money) { //jdbcTemplate.update(psc); String sql="update t_account set money=money-? where name=?"; this.getJdbcTemplate().update(sql,money,out); } public void inMoney(String in, double money) { String sql="update t_account set money=money+? where name=?"; this.getJdbcTemplate().update(sql,money,in); } }4)测试类
package com.clj.demo5;import javax.annotation.Resource;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext3.xml")public class Demo3 { @Resource(name="accountService") private AccountService accountService; @Test public void Demo1(){ //调用支付的方法accountService.pay("佳先森","李钇林",100); }}The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.