1、概念
1.spring:是一个轻量级框架,能减少代码量,包含IOC控制反转与Aop面向切面编程,使接口的实现隐藏化,更安全
2.注入方式:
-
构造器注入:IOC默认使用无参数构造方法进行创建对象
-
set注入:本质是通过类的set方法进行注入
-
设置注入:在bean里添加property标签,标签内的内容是bean的一种属性
3.IOC控制反转:通过依赖注入实现,将对象创建权利交出,无需再手动创建对象
4.Aop面向切面编程:通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术
2、使用
1.导包
<!--导入spring-webmvc包后,其他相关依赖包,maven自动导入 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.18</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.24</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
2.写pojo类
package com.jiang.Pojo;
import lombok.Data;
@Data
public class User{
private String userName;
private String age;
private String sex;
private String email;
}
3.配置 applicationContext.xml
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!--使用spring创建对象:
bean标签:id是对象名称,class对象类型,name是别名(可以取多个,用 ,;分割都可以)
property给属性赋值:name是属性名称,value是属性值,ref是指向另一个bean用的 -->
<import resource="beans2.xml"/>
<bean id="user" class="com.jiang.Pojo.User" name="u1 u2,u3;u4">
<property name="userName" value="小江"></property>
</bean>
<alias name="user" alias="myUser"/><!--给user对象取个别名myUser-->
<import resource="beans.xml"/><!--导入其他beans配置文件,相当于合并--><!--导入其他applicationContext配置文件,相当于合并-->
</beans>
4.编写测试类
import com.jiang.Pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void MyTest1() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
System.out.println(user.getUserName());
}
}
3、Bean创建有参构造的对象
public class ExampleBean {
// Fields omitted
@ConstructorProperties({"years", "ultimateAnswer"})
public ExampleBean(int years, String ultimateAnswer) {
this.years = years;
this.ultimateAnswer = ultimateAnswer;
}
}
<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg name="years" value="7500000"/><!--根据字段名来个构造函数的参数赋值-->
<constructor-arg name="ultimateAnswer" value="42"/><!--根据字段名来个构造函数的参数赋值-->
</bean>
4、Set注入复杂数据类型
package com.jiang.Pojo;
import lombok.Data;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Data
public class Student {
private int id;
private String name;
private Teacher teacher;
private int[] hobby;
private Map<String,String> stMap;
private Set<String> stSet;
private Properties info;
private String emali;
}
package com.jiang.Pojo;
import lombok.Data;
@Data
public class Teacher {
private int id;
private String name;
public int age;
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="student" class="com.jiang.Pojo.Student">
<property name="id" value="1"/>
<property name="name" value="小江"/>
<property name="teacher" ref="teacher"/>
<property name="hobby">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</property>
<property name="stMap">
<map>
<entry key="key1" value="value1"/>
<entry key="key2" value="value2"/>
</map>
</property>
<property name="stSet">
<set>
<value>just some string</value>
</set>
</property>
<property name="info">
<props>
<prop key="a">aaa</prop>
<prop key="b"></prop><!--赋值为空-->
</props>
</property>
<property name="emali">
<null/><!--赋值为null-->
</property>
</bean>
<bean id="teacher" class="com.jiang.Pojo.Teacher">
<property name="name" value="胡一天"/>
<property name="id" value="1"/>
<property name="age" value="2"/>
</bean>
</beans>
5、Bean的作用域
1.单例,默认即为单例
<bean id="student" class="com.jiang.Pojo.Student" scope="singleton">
2.原型,修改scope=“prototype”:每次从容器中get时,都会产生一个新的对象
<bean id="student" class="com.jiang.Pojo.Student" scope="prototype">
3.request,一次请求有效
4.session,一次会话有效
5.application,服务器启动到停止有效
6、Bean的自动装配
1.在xml中显示的配置
2.在java中显示的配置
3.隐式 的自动装配bean
4.注解实现@Autowired
1、在xml中新增context配置
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/><!--4、7、8、10是新增的-->
2、@Autowired可以用在属性与set方法上
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Data
public class Student {
private int id;
private String name;
@Autowired
private Teacher teacher;
private int[] hobby;
private Map<String,String> stMap;
private Set<String> stSet;
private Properties info;
private String emali;
@Autowired
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}
7、使用Java方式配置Spring
//这个java类与下面的bean配置作用相同
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
@Bean
public User myUser() {
return new User();
}
}
<beans>
<bean id="myService" class="com.acme.services.MyServiceImpl"/>
<bean id="myUser" class="com.acme.services.User"/>
</beans>
实例展示
applicationContextxml中配置扫描所有包:<context:component-scan base-package="com.jiang"/>
@Configuration
@ComponentScan("com.jiang") //可替代xml扫描所有包
public class MyConfig {
@Bean //与Bean标签效果等同,id=方法名,返回值=class属性
public User myUser(){
return new User();
}
}
@Component
@Data
public class User {
private String name;
@Value("男")
private String sex;
}
public class MyTest {
@Test
public void MyTest() {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = (User)context.getBean("myUser");
System.out.println(user.toString());//User(name=null, sex=男)
}
}
8、静态代理与动态代理
静态代理:两个对象之间的操作不直接进行,通过第三方进行代理来实现。
动态代理:在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术
代理,简单说就是:在不修改旧代码的情况下,新增一些新功能时使用
1.创建接口与实现类
//结婚接口
public interface Marry {
public void goMarry();
}
//新郎要结婚
public class Bridegroom implements Marry{
@Override
public void goMarry() {
System.out.println("新郎要结婚");
}
}
//婚庆公司实现结婚接口,静态代理类
public class Agency implements Marry {
private Bridegroom bridegroom;
public Agency() {
}
public Agency(Bridegroom bridegroom) {
this.bridegroom = bridegroom;
}
@Override
public void goMarry() {
assignTask();
treatSb();
bridegroom.goMarry();
cleanAll();
}
public void assignTask(){
System.out.println("婚庆公司 布置现场");
}
public void treatSb(){
System.out.println("婚庆公司 宴请宾客");
}
public void cleanAll(){
System.out.println("婚庆公司 清理现场");
}
}
2.使用动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
//不需代理
Bridegroom bridegroom = new Bridegroom();
bridegroom.goMarry();
System.out.println("***********************************");
//走静态代理模式
Agency agency = new Agency(bridegroom);
agency.goMarry();
System.out.println("jdk本身的动态代理机制,但是它只能代理接口,也就是Bridegroom得先有一个接口才能利用jdk动态代理机制来生成一个代理对象");
//利用JDK动态代理来生成一个代理对象:
Bridegroom target = new Bridegroom();
// UserInterface接口的代理对象
Object proxy = Proxy.newProxyInstance(Bridegroom.class.getClassLoader(), new Class[]
{Marry.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before...");
Object result = method.invoke(target, args);
System.out.println("after...");
return result;
}
});
Marry userService = (Marry) proxy;
userService.goMarry();
System.out.println("通过cglib来实现的代理对象的创建,是基于父子类的,被代理类(Bridegroom)是父类,代理类是子类,代理对象就是代理类的实例对象[这里的Bridegroom将不再需要实现Marry接口]");
Bridegroom target = new Bridegroom();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Bridegroom.class);
enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy
methodProxy) throws Throwable {
System.out.println("before...");
Object result = methodProxy.invoke(target, objects);
System.out.println("after...");
return result;
}
}});
Bridegroom userService = (Bridegroom) enhancer.create();
userService.goMarry();
}
}
9、AOP实现的三种方式
1.注解实现
1、ava类编写
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Component
@Aspect
public class Log {
@Before("execution(* com.jiang.service.*.*(..))")
public void before(){
System.out.println("之前");
}
@After("execution(* com.jiang.service.*.*(..))")
public void After(){
System.out.println("之后");
}
}
2.xml中配置
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解支持-->
<aop:aspectj-autoproxy/>
</beans>
2.其他方式参考
10、整合Mybatismybatis-spring官网
1.导包
<!-- 原有spring的包,再加上mybatis的包,和一个整合包 -->
<dependency>
<!-- 测试包 -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- 数据库驱动包,选择对应数据库的即可 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- mybatis-spring整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
2.写pojo实体类User、dao接口UserMapper、Mapper文件UserMapper.xml
import java.sql.Date;
@Data
public class User {
private int id;
private String name;
private String password;
private String email;
private String birthady;
private Date create_time;
private Date update_time;
}
import com.jiang.pojo.User;
import java.util.List;
public interface UserMapper {
List<User> getAllUser();
}
<!-- UserMapper.xml -->
<mapper namespace="com.jiang.dao.UserMapper">
<select id="getAllUser" resultType="com.jiang.pojo.User">
select * FROM UACS.jx_user
</select>
</mapper>
3.配置applicationContext.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 1.关联数据库文件。将数据库连接信息写入db.properties时,需关联 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置数据源信息 -->
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.0.110:3306/UACS?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="uacsapp" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="mapperLocations" value="com/jiang/dao/*.xml"/>
<!--引用mybatis的配置文件-->
<!-- <property name="configLocation" value="classpath:mybatis-config.xml"/>-->
</bean>
<!--使用构造方法来创建 SqlSessionTemplate 对象,取名sqlSession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<!--使用Bean来创建 UserMapperImpl对象,将sqlSession注入进去,取名userMapper-->
<bean id="userMapper" class="com.jiang.dao.UserMapperImpl">
<property name="sqlSession" ref="sqlSession" />
</bean>
</beans>
4.编写UserMapperImpl
import com.jiang.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Component;
import java.util.List;
public class UserMapperImpl implements UserMapper{
private SqlSession sqlSession;
public void setSqlSession(SqlSession sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> getAllUser() {
System.out.println("sql");
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.getAllUser();
}
}
5.编写测试类
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyTest {
@Test
public void MyTest32(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//"userMapper"是UserMapperImpl对象,UserMapper.class中的UserMapper是接口
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
List<User> allUser = userMapper.getAllUser();
for (User user : allUser) {
System.out.println(user.toString());
}
}
}
6.另一种方法实现
1、(1)(2)与上面一样,再编写实现接口的类UserDaoImpl,并继承SqlSessionDaoSupport
import com.jiang.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Component;
import java.util.List;
public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper {
public User getUser(String userId) {
return getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
}
@Override
public List<User> getAllUser() {
SqlSession sqlSession = getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
return userMapper.getAllUser();
}
}
2、配置applicationContext.xml
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置数据源信息 -->
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.0.110:3306/UACS?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="uacsapp" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1" />
<property name="mapperLocations" value="com/jiang/dao/*.xml"/>
<!--引用mybatis的配置文件-->
<!-- <property name="configLocation" value="classpath:mybatis-config.xml"/>-->
</bean>
<!--使用bean来创建 UserDaoImpl对象,将sqlSessionFactory注入进去,取名userMapper2-->
<bean id="userMapper2" class="com.jiang.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
</beans>
3、编写测试类
public class MyTest {
@Test
public void MyTest33(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//"userMapper2"是UserDaoImpl对象,UserMapper.class中的UserMapper是接口
UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
List<User> allUser = userMapper.getAllUser();
for (User user : allUser) {
System.out.println(user.toString());
}
}
}
11、事务管理
1.配置事务管理:在(10)整合的基础上,在applicationContext.xml新增配置
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置数据源信息 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.0.110:3306/UACS?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="uacsapp" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="com/jiang/dao/*.xml"/>
</bean>
<!--使用bean来创建 UserMapperImpl对象,将sqlSessionFactory注入进去,取名userMapper-->
<bean id="userMapper" class="com.jiang.dao.UserMapperImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- ***********************************新增的配置************************************************* -->
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" /><!-- 为事务管理器指定的 DataSource 必须和用来创建 SqlSessionFactoryBean 的是同一个数据源 -->
</bean>
<!--AOP实现事务的织入 -->
<!--事务管理 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- read-only开启只读,提高数据库访问性能 -->
<tx:method name="login" read-only="true" propagation="NOT_SUPPORTED" isolation="DEFAULT"/>
<!-- name是程序中的方法名称 propagation设置事务的传播性,默认为REQUIRED,当前没有事务时新建事务 -->
<tx:method name="getAllUser"/>
<!--<tx:method name="deleteUserById" />-->
<!--<tx:method name="addUser" />-->
<!--<tx:method name="*" />-->
</tx:attributes>
</tx:advice>
<!-- 事务 aop 配置 -->
<aop:config>
<!-- id:切入点名称 expression:表达式execution(要执行的位置 * * * * *) -->
<aop:pointcut id="serviceMethods" expression="execution(* com.jiang.dao.*.*(..))" />
<!-- advice-ref 通知 pointcut-ref 切入点 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
</aop:config>
<!-- ************************************************************************************ -->
</beans>
2.修改UserMapperImpl,测试事务:成功提交,失败回滚
package com.jiang.dao;
import com.jiang.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Component;
import java.util.List;
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> getAllUser() {
//getAllUser类中调用了新增与删除,只配置getAllUser方法到<tx:method中,即可实现事务管理
UserMapper userMapper = getSqlSession().getMapper(UserMapper.class);
userMapper.addUser(new User("xixi", "123456", "13123213@qq.com", "1616"));
userMapper.deleteUserById(13);
return userMapper.getAllUser();
}
@Override
public int deleteUserById(int id) {
return getSqlSession().getMapper(UserMapper.class).deleteUserById(id);
}
@Override
public int addUser(User user) {
return getSqlSession().getMapper(UserMapper.class).addUser(user);
}
}
3.注解实现事务管理
1、需要事务管理的方法上添加@Transactional
2、applicationContext.xml配置
<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
<property name="rollbackOnCommitFailure" value="true"/>
</bean>
<!-- 使用@Transactional进行声明式事务管理需要声明下面这行,使Spring事物管理的注解生效-->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
12、错误处理
Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test