1、Spring认识
1.1简介
-
Rod Johnson,Spring Framework创始人
-
是现有的技术更加容易结合使用,整合技术框架
-
SSM:Spring + SpringMVC + Mybatis
-
SSH: Struct2 + Spring +Hibernate
官网:https://spring.io/projects/spring.framework#overview
1.2优点
- 开源免费的框架
- 轻量级的、非入侵式的框架
- 控制反转(IOC),面向切面编程(AOP)
- 支持事务的处理,对框架整合的支持
2、IOC(控制反转)
在我们之前的业务中,用户的需求变更可能会影响我们原来的代码,我们需要根据变更来修改原来的代码,这样操作会使改的代码量十分大
所以 我们要使用一个Set接口实现值的注入
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
this.userDao.getUser();
}
}
- 之前,程序是主动创建对象!控制权在程序猿手上
- 使用set注入后,程序不在具有主动性,而是变成了被动接受的对象
这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建。系统耦合性大大降低
3、Bean的装配
3.1 基于XML
1.属性set注入
<bean id="student" class="com.kk.pojo.Student">
<!-- 1.普通注入-->
<property name="name" value="wkx"/>
<!-- 2.bean注入-->
<property name="address" ref="address"/>
<!-- 3.数组注入-->
<property name="book">
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
</bean>
2.属性构造注入
<bean id="address" class="com.kk.pojo.Address">
<property name="address" value="CS"/>
</bean>
<bean id="student1" class="com.kk.pojo.Student1">
<constructor-arg index="0" value="wkx"/>
<constructor-arg index="1" ref="address"/>
</bean>
3.自动装配(autowire=“byType/byName”)
EXAMPLE 一个人有两只宠物
pojo类
public class People
{
private String name;
private Cat cat;
private Dog dog;
}
public class Cat {
public void shout()
{
System.out.println("miao~");
}
}
public class Dog {
public void shout()
{
System.out.println("wang~");
}
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.kk.po.Cat"/>
<bean id="dog" class="com.kk.po.Dog"/>
<!-- 1 byName 自动装配-->
<bean id="people" class="com.kk.po.People" autowire="byName">
<property name="name" value="wkx"/>
</bean>
<!-- 2 byType 自动装配-->
<bean id="people" class="com.kk.po.People" autowire="byType">
<property name="name" value="wkx"/>
</bean>
</beans>
注意:
-
如果是byName自动装配,默认匹配set后的小写名字,如setCat()方法,就自动匹配id等于cat的bean
-
如果是byType自动装配,根据类型来匹配,如以下的cat,它是Cat类型的Bean,所以在自动装配时,会去Bean的容器里寻找这一类型的Bean
测试
public class MyTest {
@Test
public void test1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
People people = applicationContext.getBean("people",People.class);
people.getCat().shout();
people.getDog().shout();
}
}
结果
miao~
wang~
3.2 基于Annotation(Spring4后,要依赖aop包)
注解说明
-@Component:可以放在所有类上,说明这个类被Spring容器管理了
衍生注解
-@Repository:Dao层
-@Service:Service层
-@Controller:Servlet层
自动装配
-@Autowired:自动装配 默认byType
如果Autowired不能唯一自动装配属性,则需要@Qualifier(value=""")
-@Resource:自动装配 默认先byName后byType
1.属性注入 @Value
// 等价<bean id="user" class="com.kk.po.User"/>
@Component("user")
public class User {
// 相当于<property name="name" value="wkx"/>
public String name;
@Value("wkx")
public void setName(String name) {
this.name = name;
}
}
2.自动装配
@Data
public class People {
private String name;
@Autowired
private Cat cat;
@Autowired
private Dog dog;
}
<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1.指定要扫描的包,这个包下的注解即生效-->
<context:component-scan base-package="com.kk"/>
<!-- 2.开启属性注解支持-->
<context:annotation-config/>
<!-- 3.配置Bean-->
<bean class="com.kk.po.People" id="people"/>
<bean id="cat" class="com.kk.po.Cat"/>
<bean id="dog" class="com.kk.po.Dog"/>
</beans>
-
@Qualifier配合@Autowired
@Data public class People { private String name; //@Autowired直接在属性或者set方法上 @Autowired @Qualifier(value="cat222") private Cat cat; @Autowired @Qualifier(value="dog222") private Dog dog; }
<?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 https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 1.指定要扫描的包,这个包下的注解即生效--> <context:component-scan base-package="com.kk"/> <!-- 2.开启属性注解支持--> <context:annotation-config/> <!-- 3.配置Bean--> <bean class="com.kk.po.People" id="people"/> <bean id="cat222" class="com.kk.po.Cat"/> <bean id="dog222" class="com.kk.po.Dog"/> </beans>
-
@Resource 先byName后byType
public class People { private String name; //@Autowired直接在属性或者set方法上 @Resource //name值等于bean上装配的id值 private Cat cat; @Resource(name="dog222") private Dog dog; }
<?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 https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 1.指定要扫描的包,这个包下的注解即生效--> <context:component-scan base-package="com.kk"/> <!-- 2.开启属性注解支持--> <context:annotation-config/> <!-- 3.配置Bean--> <bean class="com.kk.po.People" id="people"/> <bean id="cat222" class="com.kk.po.Cat"/> <bean id="dog222" class="com.kk.po.Dog"/> </beans>
-
测试
public class MyTest { @Test public void test1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); People people = applicationContext.getBean("people",People.class); people.getCat().shout(); people.getDog().shout(); } }
@Autowired 和 @Resource 的区别
-
都是用来自动装配的,可以放在属性字段上或set方法上
-
@Autowired先通过byType,后byName
-
@Resource反之
-
3、作用域 @Scope
@Component("user")
@Scope("prototype")
public class User {
// 相当于<property name="name" value="wkx"/>
public String name;
@Value("wkx")
public void setName(String name) {
this.name = name;
}
}
xml与Annotation
- xml更加万能,适用任何场景,维护简单方便
- 维护相对复杂
最佳实践
- xml用来管理bean
- 注解只负责完成属性的注入
- 注解生效
4、AOP
4.1代理模式(SpringAOP底层)
好处:
-
可以使真实角色的操作更加纯粹
-
公共业务交给代理角色 实现业务分工
-
公共业务发生拓展时,方便集中管理
缺点:
- 一个真实的代理角色会产生一个代理角色;代码量翻倍,开发效率降低
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bsuKhumq-1625567032574)(D:\桌面文件夹\1.png)]
分类
4.2 静态代理
角色分析:
抽象角色:租房
public interface Rent {
public void rent();
}
真实角色:房东
public class Host implements Rent {
public void rent() {
System.out.println("房东要出租房子");
}
}
代理角色:中介
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent() {
host.rent();
}
//看房
public void seeHouse(){
System.out.println("看房");
}
//签租赁合同
public void contact(){
System.out.println("签合同");
}
}
被代理角色:租客
public class Client {
public static void main(String[] args) {
Host host = new Host();
//host.rent();
// 代理模式
Proxy proxy = new Proxy(host);
//租客直接找中介租房即可,无需通过房东
proxy.rent();
}
}
public class MyTest {
//@Test
public void t1(){
Proxy proxy = new Proxy(new Host());
proxy.rent();
}
}
4.3 动态代理
-
动态代理和静态代理角色一样
-
动态代理的代理类时动态生成的,不是直接写好的
-
实现方式:基于接口的JDK动态代理,基于CGLIB类的动态代理
-
基于接口—JDK代理 InvocationHandler&&Proxy
-
基于类—CGLIB
-
java字节码 javassist
-
//用这个类,自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
//处理代理实例,并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质,就是使用反射机制实现的
log(method.getName());
Object result = method.invoke(target,args);
return result;
}
public void log(String msg){
System.out.println("执行力"+msg+"方法");
}
}
public class Client {
public static void main(String[] args) {
//真实角色
UserService userService = new UserServiceImpl();
//代理角色,不存在
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
//设置要代理的对象
proxyInvocationHandler.setTarget(userService);
//动态生成代理类
UserService proxy = (UserService) proxyInvocationHandler.getProxy();
proxy.add();
}
}
动态代理的好处:
- 一个动态代理可以代理多个类,代理的是接口
4.4 AOP的实现
4.4.1使用SPring实现
【重点】使用AOP织入,需要导入一个依赖包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
自定义类来实现AOP
声明一个UserService接口、一个实现类、一个自定义切面类
public interface UserService {
void add();
void delete();
void update();
void select();
}
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("增加了一个用户");
}
public void delete() {
System.out.println("删除了一个用户");
}
public void update() {
System.out.println("更新了一个用户");
}
public void select() {
System.out.println("查询了一个用户");
}
}
//自定义切面
public class Log {
//通知
public void log(){
System.out.println("输出日志");
}
public void after(){
System.out.println("方法执行后");
}
}
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: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
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 1 注册Bean-->
<bean id="userService" class="com.kk.service.UserServiceImpl"/>
<bean id="log" class="com.kk.log.Log"/>
<!-- 2 配置AOP-->
<aop:config>
<!-- 2.1 自定义切面类-->
<aop:aspect ref="log">
<!-- 2.2 切入点 -->
<aop:pointcut id="pointcut" expression="execution(* com.kk.service.UserServiceImpl.*(..))"/>
<!-- 2.3通知-->
<aop:before method="log" pointcut-ref="pointcut"/>
<aop:after-returning method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
使用注解实现
@Aspect
public class AnnotationAspect {
@Before("execution(* com.kk.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("方法执行前");
}
@After("execution(* com.kk.service.UserServiceImpl.*(..))")
public void After(){
System.out.println("方法执行后");
}
@Around("execution(* com.kk.service.UserServiceImpl.*(..))")
//在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前");
joinPoint.proceed();//执行方法
System.out.println("环绕后");
}
}
@Service("userService")
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("增加了一个用户");
}
public void delete() {
System.out.println("删除了一个用户");
}
public void update() {
System.out.println("更新了一个用户");
}
public void select() {
System.out.println("查询了一个用户");
}
}
@Service
public interface UserService {
void add();
void delete();
void update();
void select();
}
public class MyTest {
@Test
public void test2(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext1.xml");
UserService userService = applicationContext.getBean("userService",UserService.class);
userService.delete();
}
}
5、Spring整合MyBatis
5.1 MyBatis步骤
- 整合包(Maven Repository)
- junit
- mysql-connector
- mybatis
- spring-webmvc
- spring-jdbc
- 【aop织入】aspectjweaver
- mybatis-spring
- 编写配置文件
- 测试
5.2 MyBatis-Spring
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession
并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException
。 最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。
要和 Spring 一起使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory
和至少一个数据映射器类。
5.3 整合实现
5.3.1基于MapperFactoryBean(sqlSessionTemplate)
-
编写数据源配置
<!-- DataSource:使用Spring的数据源替换MyBatis的配置,c3p0,Druid,dbcp--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean>
-
sqlSessionFactory
<!-- sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 指定mybatis配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <!-- 指定mapper文件--> <property name="mapperLocations" value="classpath:com/kk/dao/*.xml"/> </bean>
-
sqlSessionTemplate
<bean id="Template" class="org.mybatis.spring.SqlSessionTemplate"> <!-- 只能用构造器注入,无set方法--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean>
-
添加事务管理器
<!--配置mybatis工厂 sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 指定mybatis配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <!-- 指定mapper文件--> <property name="mapperLocations" value="classpath:com/kk/dao/*.xml"/> </bean>
-
给接口添加实现类
public class UserMapperImpl implements UserMapper { //mybatis时,我们使用sqlSession来执行增删改查等方法,整合以后,使用SqlSessionTemplate private SqlSessionTemplate sqlSession; public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } public User getUserById(int id) { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.getUserById(id); } }
-
将自己写的实现类注入Spring容器中()
<bean id="userMapper" class="com.kk.dao.UserMapperImpl"> <property name="sqlSession" ref="Template"/> </bean>
-
测试
public class MyTest { @Test public void test1(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = applicationContext.getBean("userMapper",UserMapper.class); System.out.println( userMapper.getUserById(2)); } }
5.3.2基于MapperScannerConfigurer
基于以上,删除配置UserMapperImpl.java文件,且删除userMapper Bean的配置,替换成以下这个
<!-- 6 使用mapper代理开发(基于MapperScannerConfigurer) 无需自己手动配置mapper,自动通过包中的接口扫描,找到映射器Mapper.xml -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.kk.dao"/>
</bean>
条件:
- Mapper接口名称和对应Mapper.xml映射文件名称一致
- Mapper.xml中namespace与Mapper接口类路径一致,即接口文件和映射文件在同一包下
- Mapper接口中的方法输入、输出参数类型与Mapper.xml中一致
5.3.3 基于SqlSessionDaoSupport(由其自带的getSession获取SqlSession对象)
- UserServiceImpl.java
public class UserServiceImpl extends SqlSessionDaoSupport implements UserService {
public List<User> getUserList() {
return getSqlSession().getMapper(UserMapper.class).getUserList();
}
}
- 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1 读取db.properties文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 2 配置数据源DataSource:使用Spring的数据源替换MyBatis的配置,c3p0,Druid,dbcp-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--3 装配SqlSessionFactory-->
<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--读取mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 4 装配SqlSession-->
<bean id="SqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="SqlSessionFactory"/>
</bean>
<!--5 自动装配Mapper-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.kk.dao"/>
</bean>
<!--6 装配Bean-->
<bean class="com.kk.service.UserServiceImpl" id="userService">
<property name="sqlSessionFactory" ref="SqlSessionFactory"/>
</bean>
</beans>
6、Spring中的事务管理
一组事务中,如果在没配置事务管理时,有一个方法可以正确执行时,则会更新数据库;如果加入了事务管理,必须满足ACID原则,要么全做,要么全不做。
一个使用 MyBatis-Spring 的其中一个主要原因是它允许 MyBatis 参与到 Spring 的事务管理中。
6.1编程式事务(略)
6.2声明式事务(AOP)
开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager
对象:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
**注意:**为事务管理器指定的 DataSource 必须和用来创建 SqlSessionFactoryBean 的是同一个数据源,否则事务管理器就无法工作了。
交由容器管理事务 结合使用AOP(在不改变源代码,横向织入)
<?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:tx="http://www.springframework.org/schema/tx" 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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解-->
<context:annotation-config/>
<context:component-scan base-package="com.kk"/>
<!-- 1 读取db.properties文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 2 配置数据源DataSource:使用Spring的数据源替换MyBatis的配置,c3p0,Druid,dbcp-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--3 装配SqlSessionFactory-->
<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--读取mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 4 装配SqlSession-->
<bean id="SqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="SqlSessionFactory"/>
</bean>
<!--5 自动装配Mapper-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.kk.dao"/>
</bean>
<bean class="com.kk.service.UserServiceImpl" id="userService">
<property name="sqlSessionFactory" ref="SqlSessionFactory"/>
</bean>
<!--6 配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<!--6.1结合AOP实现事务织入-->
<!--6.2配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--6.3给哪些方法配置事务-->
<!--6.4 配置事务传播特性 propagation默认REQUIRED,可以不写-->
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="delete" propagation="REQUIRED"/>
<tx:method name="update" propagation="REQUIRED"/>
<tx:method name="query" read-only="true"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--7 配置事务切入-->
<aop:config>
<!--7.1切入点-->
<aop:pointcut id="pointCut" expression="execution(* com.kk.service.*.*(..))"/>
<!--7.2切面:将切入点和通知整合-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
</beans>
7、未完待续(思路不太清晰)、、、主要用于复习