Spring5基础

spring的优点

1、spring是一个开源的免费框架
2、spring是一个轻量级的,非入侵式的框架
3、控制反转(IOC),面向切面(AOP)
4、支持事务处理,对框架整合支持

IOC底层原理

1、什么是 IOC
(1)控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理
(2)使用 IOC 目的:为了耦合度降低
(3)做入门案例就是 IOC 实现
2、IOC 底层原理
(1)xml 解析、工厂模式、反射
3、画图讲解 IOC 底层原理
IOC(BeanFactory 接口)
1、IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂
2Spring 提供 IOC 容器实现两种方式:(两个接口)
(1BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用
* 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
(2ApplicationContextBeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人
员进行使用
* 加载配置文件时候就会把在配置文件对象进行创建
3ApplicationContext 接口有实现类

Bean管理创建对象并实现属性注入的配置

1、创建要用IOC创建的类Book(例子)
2、创建beans.xml配置文件进行如下配置
 <!--配置对象的创建-->
 // id 类的唯一标识  class为类的全类名
 <!--配置属性注入  使用类中set方法进行属性注入->
  <bean id="book" class="com.spring5.demo1.pakage1.Book">
		    //name属性名称 value属性的值   
		    <property name="bname" value="西游记"></property>
		    <property name="bauthor" value="吴承恩"></property>
		    //设置address属性为空值
		    <property name="address">
		       <null/>
		    </property>
		    //该种配置方式可以让属性值含有特殊符号 
		     <property name="address">
		       <value><![CDATA[属性值]]></value>
		    </property>
  </bean>
<!--配置属性注入  使用类中有参构造函数进行属性注入->
 <bean id="book" class="com.spring5.demo1.pakage1.Book">
		<constructor-arg name="name" value="sss"></constructor-arg>
        <constructor-arg name="address" value="china"></constructor-arg>
 </bean>
	
<!--配置属性注入 p名称空间注入-->(了解) //需要添加 xmlns:p="http://www.springframework.org/schema/p"
<bean id="book" class="com.spring5.demo1.pakage1.Book" p:bname="sss" p:bauthor="aaa"></bean>

//注入属性外部bean的配置
//以下配置为属性注入对象
<bean id="UserService" class="com.spring5.demo1.service.UserService">
<property name="userDao" ref="UserDaoImpl"></property>
</bean>
<bean id="UserDaoImpl" class="com.spring5.demo1.dao.UserDaoImpl"></bean>

//注入属性内部bean的配置
<bean id="employee" class="com.spring5.demo1.pakage1.Employee">
	    <property name="ename" value="ssss"></property>
	    <property name="gender" value="女"></property>
	    <property name="department">
		      <bean id="department" class="com.spring5.demo1.pakage1.Department">
			        <property name="dname" value="安保部"></property>
		      </bean>
	    </property>
</bean>

//配置属性 级联赋值
第一种写法:
     <bean id="employee" class="com.spring5.demo1.pakage1.Employee">
			 <property name="ename" value="ssss"></property>
			 <property name="gender" value="女"></property>
			 <property name="department" ref="department"></property>
     </bean>
     <bean id="department" class="com.spring5.demo1.pakage1.Department">
           <property name="dname" value="安保部"></property>
     </bean>
 第二种写法:
  <bean id="employee" class="com.spring5.demo1.pakage1.Employee">
	    <property name="ename" value="ssss"></property>
	    <property name="gender" value="女"></property>
	    <property name="department" ref="department"></property>
	    //要有getDepartment()的方法
	    <property name="department.dname" value="技术部"></property>
  </bean>
  <bean id="department" class="com.spring5.demo1.pakage1.Department">
        <property name="dname" value="安保部"></property>
  </bean>

//注入array、list、map、set属性
<bean id="stu" class="com.spring5.bean.Student">
        <!--注入数组属性-->
        <property name="array">
            <array>
                <value>元素1</value>
                <value>元素2</value>
                <value>元素3</value>
            </array>
        </property>

        <!--注入list属性-->
        <property name="list">
            <list>
                <value>list1</value>
                <value>list1</value>
                <value>list1</value>
                <value>list1</value>
            </list>
        </property>

        <!--注入map属性-->
        <property name="maps">
            <map>
                <entry key="键" value="值"></entry>
                <entry key="键" value="值"></entry>
                <entry key="键" value="值"></entry>
            </map>
        </property>

        <!--注入set属性-->
        <property name="set">
            <set>
                <value>set1</value>
                <value>set1</value>
                <value>set1</value>
            </set>
        </property>
    </bean>


 <!--//list类型的集合中注入对象类型的值-->
    <bean id="student" class="com.spring5.bean.Student">
        <property name="courses">
            <list>
                <ref bean="course1"></ref>
                <ref bean="course2"></ref>
            </list>
        </property>
    </bean>
    <bean id="course1" class="com.spring5.bean.Course">
        <property name="cname" value="数据结构"></property>
    </bean>
    <bean id="course2" class="com.spring5.bean.Course">
        <property name="cname" value="大话数据结构"></property>
    </bean>



3、读取beans.xml配置文件 实现对象的创建
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Book book = context.getBean("book", Book.class);
book.testBook();

Bean管理提取内容后 再完成注入

1、引入名称空间util
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd">
//提取内容
 <util:list id="bookList">
        <value>提取元素1</value>
        <value>提取元素2</value>
        <value>提取元素3</value>
        <value>提取元素4</value>
    </util:list>
//注入
 <bean id="person" class="com.spring5.bean.Person">
        <property name="list" ref="bokList"></property>
 </bean>
 //提取的内容也可注入到其他对象中相对应得属性中

bean 的作用域

1、在spring里面设置bean是单实例还是多实例
  在spring的配置文件里面bean标签有scope属性
  scope的属性值
  singleton 默认的 单实例对象
  prototype 多实例对象
  singleton和prototype的区别: 前者会在spring加载配置文件时就创建单实例对象 后者条用getBean()方法时创建多实例对象

Bean生命周期

2、bean 生命周期
(1)通过构造器创建 bean 实例(无参数构造)
(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
(3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
(4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization
(6)bean 可以使用了(对象获取到了)
(7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
public class Person {
    private String name;

    public Person() {
        System.out.println("第一步:调用无参构造函数创建实例");
    }

    public void setName(String name) {
        this.name = name;
        System.out.println("第二步:调用set方法注入属性");
    }

    public void initMethod() {
        System.out.println("第四步:调用初始化方法");
    }

    public void  destoryMethod() {
        System.out.println("第七步:调用销毁方法");
    }
}

//后置处理器的创建  创建一个类实现BeanPostProcessor
public class MyPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(" 第三步 :在初始化之前调用");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第五步 :在初始化之后调用");
        return bean;
    }
}

//在beans.xml中的配置

  <bean id="person" class="com.spring5.demo1.pakage1.Person" init-method="initMethod" destroy-method="destoryMethod">
    <property name="name" value="zhang"></property>
  </bean>
  <bean id="myPost" class="com.spring5.demo1.pakage1.MyPost"></bean>

读取配置文件(配置druid数据库连接池为例)

1、引入context名称空间
<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"
       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">
2、引入外部文件
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
3、配置连接池
  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${prop.driverClassName}"></property>
    <property name="url" value="${prop.url}"></property>
    <property name="username" value="${prop.url}"></property>
    <property name="password" value="${prop.password}"></property>
  </bean>

基于注解方式实现对象的创建和属性注入

1Spring针对Bean管理创建对象的注解
   >@Component  一般用在servlet层
   >@Service  一般用在service层
   >@Controller 一般用在web层
   >@Reposity  一般用在Dao层
   上面四个功能一样 用来创建对象
2、 基于注解方式创建对象
   第一步:引入spring-aop-5.2.6.RELEASE.jar 依赖
   第二步:开启组件扫描
     <!--组件扫面-->
     <!--base-package 包的路径-->
    <context:component-scan base-package="com.spring5"></context:component-scan>
  
  第三步:对要创建对象的类加上注解
       @Component(value="userService")
       public class UserService {
            public void add() {
                    System.out.println("add");
            }
        }
  第四步:得到创建的对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService = context.getBean("userService",UserService.class);
        userService.add();

3、组件扫描的细节配置
   //<!--use-default-filters="false" 表示不使用默认的filter 使用自己配置的filter 不用扫描全部的类-->
    <context:component-scan base-package="com.spring5" use-default-filters="false">
       // <!--context:include-filter  自己配置的filter  只扫描包中有Controller类型注解的类-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <context:component-scan base-package="com.spring5">
        <!--包中有Controller注解的类不扫描  其余的类都扫描-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

基于注解的方式实现属性注入

1Spring针对Bean管理注入属性的注解
  >@AutoWired  根据先类型 后名字进行注入 不需添加set方法
  >@Qualifier  根据名字进行注入 要和@AutoWired 一起使用
  >@Resource  根据先名字进行注 也可根据类型进行注入
   // @Resource 类型注入
    @Resource(name = "userDaoImpl1") //名字注入
    private UserDao userDao;
 >@value 注入普通属性
  
  @Value(value="abs")
  private String name;


完全注解开发

1、创建配置类 代替xml配置文件

@Configuration //创建配置类 代替xml配置文件
@ComponentScan(basePackages = {"com.spring5"})
public class SpringConfig {
}
其他属性注入方式不变
2、获得创建的对象
 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
 UserService userService = context.getBean("userService", UserService.class);
 userService.service();

AOP

a)连接点:类里面哪些方法可以被增强,这些方法称为连接点

​ b)切入点:实际被真正增强的方法称为切入点

​ c)通知(增强):实际增强的逻辑部分称为通知,且分为以下五种类型:

​          1)前置通知 2)后置通知 3)环绕通知 4)异常通知 5)最终通知

​ d)切面:把通知应用到切入点过程


(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强 
(2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )3)例子如下:
    例 1:对 com.atguigu.dao.BookDao 类里面的 add 进行增强
		execution(* com.atguigu.dao.BookDao.add(..))2:对 com.atguigu.dao.BookDao 类里面的所有的方法进行增强
		execution(* com.atguigu.dao.BookDao.* (..))3:对 com.atguigu.dao 包里面所有类,类里面所有方法进行增强
		execution(* com.atguigu.dao.*.* (..))

注解的方式实现aop操作

1、创建类,在类里面定义方法
public class User {
 public void add() {
 System.out.println("add.......");
 }
}
2、创建增强类(编写增强逻辑)
(1)在增强类里面,创建方法,让不同方法代表不同通知类型
//增强的类
public class UserProxy {
   //在增强类中可以配置不同类型的通知
}
3、进行通知的配置
	(1)在 spring 配置文件中,开启注解扫描
	<?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
	    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">
	  <!-- 开启注解扫描 -->
	  <context:component-scan basepackage="com.atguigu.spring5.aopanno"></context:component-scan>
  </beans>
 
4、使用注解创建UserUserProxy的对象
@Component
public class User {
    public void add() {
        System.out.println("add.....");
    }
}
@Component
public class UserProxy {
  //在增强类中可以配置不同类型的通知
}

5、在增强类上面添加注解 @Aspect
@Component
@Aspect
public class UserProxy {
  //在增强类中可以配置不同类型的通知
}
6、在spring配置文件中开启生成代理对象
  <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
7、在增强类中配置不同类型的通知
@Component
@Aspect
public class UserProxy {
    // 前置通知
    @Before(value = "execution(* com.spring5.aop.User.add(..))")
    public void before() {
        System.out.println("before.....");
    }
    //后置通知  有异常不执行 返回结果后执行
    @AfterReturning(value = "execution(* com.spring5.aop.User.add(..))")
    public void afterReturning() {
        System.out.println("AfterReturning.....");
    }
    //最终通知 有无异常都执行
    @After(value = "execution(* com.spring5.aop.User.add(..))")
    public void after() {
        System.out.println("After.....");
    }
    //异常通知
    @AfterThrowing(value = "execution(* com.spring5.aop.User.add(..))")
    public void afterThrowing() {
        System.out.println("AfterThrowing.....");
    }
    //环绕通知
    @Around(value = "execution(* com.spring5.aop.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("Around  之前.....");
        proceedingJoinPoint.proceed();
        System.out.println("Around  之后.....");
    }

}

8、相同切入点的抽取
@Component
@Aspect
public class UserProxy {

    @Pointcut(value="execution(* com.spring5.aop.User.add(..))")
    public void pointDemo() {
    }
    // 前置通知
    @Before(value = "pointDemo()")
    public void before() {
        System.out.println("before.....");
    }
    //后置通知  有异常不执行 返回结果后执行
    @AfterReturning(value = "pointDemo()")
    public void afterReturning() {
        System.out.println("AfterReturning.....");
    }
    //最终通知 有无异常都执行
    @After(value = "pointDemo()")
    public void after() {
        System.out.println("After.....");
    }
    //异常通知
    @AfterThrowing(value = "pointDemo()")
    public void afterThrowing() {
        System.out.println("AfterThrowing.....");
    }
    //环绕通知
    @Around(value = "pointDemo()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("Around  之前.....");
        proceedingJoinPoint.proceed();
        System.out.println("Around  之后.....");
    }

}
9、有多个增强类对同一个方法进行增强,设置增强类的优先级
在增强类上面添加注解@Order(数字) 数字越小 优先级越高

10、完全注解发 创建一个配置类来代替bean.xml文件中的配置
@Configuration
@ComponentScan(basePackages = {"com.spring5"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
}

bean.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 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">
       <!--开启注解扫描-->                    
    <context:component-scan base-package="com.spring5.aop"></context:component-scan>
    <!--开启Aspect生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

JdbcTemplate对数据库的操作

操作之前的配置
<?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 id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
    <!--JdbcTemplate对象-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <context:component-scan base-package="com.spring5"></context:component-scan>
</beans>

增删改查的操作
 
@Repository
public class BookDaoImpl implements BookDao {
    //注入jdbcTemplate对象
    @Autowired
    private JdbcTemplate jdbcTemplate;

    //增
    @Override
    public void add(Book book) {
        String sql = "insert into t_book values(?,?,?)";
        int update = jdbcTemplate.update(sql, book.getBookId(), book.getBookName(), book.getBookStatus());
        System.out.println(update);
    }
    //改
    @Override
    public void update(String newName,String id) {
        String sql = "update t_book set bookName = ? where bookId = ?";
        int update = jdbcTemplate.update(sql, newName, id);
        System.out.println(update);
    }
    //删
    @Override
    public void delete(String id) {
        String sql = "delete from t_book where bookId = ?";
        int update = jdbcTemplate.update(sql, id);
        System.out.println(update);
    }

    @Override
    public int selectCount() {
        String sql = "select count(*) from t_book";
        Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
        return count;
    }

    @Override
    public Book findBookInfo(String id) {
        String sql = "select * from t_book where bookId = ?";
        Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id);
        return book;
    }

    @Override
    public List<Book> findAllBookInfo() {
        String sql = "select * from t_book";
        List<Book> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class));
        return query;
    }

    //批量添加
    @Override
    public void batchAdd(List<Object[]> list) {
        String sql = "insert into t_book values(?,?,?)";
        //Object[] 中的元素对应 ?代表的值
        int[] ints = jdbcTemplate.batchUpdate(sql, list);
        System.out.println(ints);
    }

    //批量修改

    @Override
    public void batchUpdate(List<Object[]> list) {
        String sql = "update t_book set bookName = ? where bookId = ?";
        //Object[] 中的元素对应 ?代表的值
      int[] ints = jdbcTemplate.batchUpdate(sql, list);
        System.out.println(Arrays.toString(ints));
    }

    //批量删除
    public void batchDelete(List<Object []> list){
        String sql = "delete from t_book where bookId = ?";
        int[] ints = jdbcTemplate.batchUpdate(sql, list);
        System.out.println(Arrays.toString(ints));
    }
}

注解的方式实现声明式事务管理(推荐使用)

 1、创建事务管理器
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
 2、引入tx名称空间
 <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"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
 3、启事务注解
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
 4、在service类(或在service类中)添加事务注解
   >@Transactional


beans.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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--开启组件扫描-->
    <context:component-scan base-package="com.spring5"></context:component-scan>
    
    <!--配置数据库连接池-->                           
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>
    <!--jdbcTemplate对象 操作数据库-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--开启事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

</beans>

声明式事务管理参数配置

1、propagation  事务的传播行为
  最常见的两种:
     >REQUIRED  如果A方法有事务 调用B方法后 B方法使用A方法当前的事务   
                如果A方法没有事务 调用B方法后 创建新事务
     >REQUIRED_NEW  	A方法有没有事务 调用B方法后 都创建新事务
  @Transactional(propagation = Propagation.REQUIRED)
2、隔离级别
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
3、超时时间
(1)、事务需要在一定时间内提交,如不提交进行回滚
(2)、默认值为-1,设置以秒为为单位进行计算
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ,timeout = -1)
4、readOnly
默认值为false  改为true后只能查询 不能对数据进行修改
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ,timeout = -1,readOnly = false)
5、rollbackFor: 回滚
设置出现那些异常进行回滚
6、noRollbackFor: 不回滚
设置出现那些异常不进行回滚

xml方式实现声明式事务管理

1、配置事务管理器
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
2、配置通知
<tx:advice id="txAdvice">
        <tx:attributes>
            <tx:method name="account*" isolation="REPEATABLE_READ"></tx:method>
        </tx:attributes>
    </tx:advice>
 3、配置切入点和切面
 

完全注解的方式实现声明式事务管理

创建的配置类

@Configuration
@ComponentScan(basePackages = "com.spring5")
@EnableTransactionManagement //开启事务
public class Transaction {

    //创建数据库连接池对象
    @Bean
    public DruidDataSource getDruidDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        return dataSource;
    }
    //jdbcTemplate对象
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource) {

        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
    //事务管理对象
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }

}


测试:
@Test
public void test1() {
        ApplicationContext context = new AnnotationConfigApplicationContext(Transaction.class);
        AccountService accountService = context.getBean("accountService", AccountService.class);
        accountService.transferAccounts();
 }

xml配置文件实现对象的创建以及各种类型属性的注入

1、实体类
public class Student {

    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbies;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties info;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public Map<String, String> getCard() {
        return card;
    }

    public void setCard(Map<String, String> card) {
        this.card = card;
    }

    public Set<String> getGames() {
        return games;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "com.demo2.bean.Student{" +
                "name='" + name + '\'' +
                ", address=" + address +
                ", books=" + Arrays.toString(books) +
                ", hobbies=" + hobbies +
                ", card=" + card +
                ", games=" + games +
                ", wife='" + wife + '\'' +
                ", info=" + info +
                '}';
    }
}


配置文件
<?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.demo2.bean.Student">
<!--        基本类型注入-->
        <property name="name" value="jack"></property>
<!--        对象注入-->
        <property name="address" ref="address"></property>
        <!--数组注入-->
        <property name="books">
            <array>
                <value>三国演义</value>
                <value>西游记</value>
                <value>水浒传</value>
                <value>红楼梦</value>
            </array>
        </property>
<!--        list注入-->
        <property name="hobbies">
            <list>
                <value>听歌</value>
                <value>打游戏</value>
                <value>看电影</value>
            </list>
        </property>

<!--        map注入-->
        <property name="card">
            <map>
                <entry key="身份证" value="122345623565"></entry>
                <entry key="银行卡" value="545465568989"></entry>
            </map>
        </property>
<!--        set注入-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>Steam</value>
                <value>DNF</value>
            </set>
        </property>
<!--        null注入-->
        <property name="wife">
            <null/>
        </property>
<!--        properties注入-->
        <property name="info">
            <props>
                <prop key="driver">com.mysql.jdbc.Driver</prop>
                <prop key="url">jdbc:mysql://localhost:3306/mybatis</prop>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>
    <bean id="address" class="com.demo2.bean.Address">
        <property name="province" value="HeNan"></property>
        <property name="city" value="ZouKou"></property>
    </bean>
</beans>

bean的作用域

1、singleton  默认 单例模式
<bean id="address" class="com.demo2.bean.Address" scope="singleton">
        <property name="province" value="HeNan"></property>
        <property name="city" value="ZouKou"></property>
 </bean>
 2、prototype 原型模式  每次从容器中取对象,都会产生一个新的对象
 <bean id="address" class="com.demo2.bean.Address" scope="prototype">
        <property name="province" value="HeNan"></property>
        <property name="city" value="ZouKou"></property>
    </bean>
 3、其余的request、session、application在web开发中会用到

bean的自动装配

实体类
public class People {

    private String name;
    private Dog dog;
    private Cat cat;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", dog=" + dog +
                ", cat=" + cat +
                '}';
    }
}


public class Dog {

    public void shout() {
        System.out.println("汪汪。。。。");
    }
}


public class Cat {
    public void shout() {
        System.out.println("喵喵。。。。");
    }
}


//beans.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="cat" class="com.demo2.bean.Cat"></bean>
    <bean id="dog" class="com.demo2.bean.Dog"></bean>

<!--     根据名字自动装配 注入的bean的id唯一 并且该bean的id需要和注入属性set方法后值对应-->
<!--    <bean id="people" class="com.demo2.bean.People" autowire="byName">-->
<!--        <property name="name" value="jack"></property>-->
<!--    </bean>-->
<!--    根据类型注入 注入的bean的class唯一 该bean要和注入属性的类型保持一致-->
    <bean id="people" class="com.demo2.bean.People" autowire="byType">
        <property name="name" value="jack"></property>
    </bean>
</beans>

AOP实现方式一 (Spring的API)

//增强类
public class AfterMethod implements AfterReturningAdvice {
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("add返回值之后执行了");
    }
}

public class BeforeMethod implements MethodBeforeAdvice {
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("add之前执行");
    }
}


//被增强类
public class UserServiceImpl implements UserService {
    public void add() {
        System.out.println("add.....");
    }

    public void delete() {
        System.out.println("delete.....");
    }

    public void update() {
        System.out.println("update.....");
    }

    public void query() {
        System.out.println("query.....");
    }
}


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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">



   <bean id="userService" class="com.demo1.aop.service.UserServiceImpl"></bean>
  <bean id="afterMethod" class="com.demo1.aop.log.AfterMethod"></bean>
   <bean id="beforeMethod" class="com.demo1.aop.log.BeforeMethod"></bean>   
   
 <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* com.demo1.aop.service.UserServiceImpl.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="afterMethod" pointcut-ref="pointcut"></aop:advisor>
        <aop:advisor advice-ref="beforeMethod" pointcut-ref="pointcut"></aop:advisor>

    </aop:config>
</beans>

AOP实现方式二 自定义切面

自定义的增强类

public class DefineClass {

    public void before() {
        System.out.println("before.....");
    }

    public void after() {
        System.out.println("after......");
    }
}


//被增强类
public class UserServiceImpl implements UserService {
    public void add() {
        System.out.println("add.....");
    }

    public void delete() {
        System.out.println("delete.....");
    }

    public void update() {
        System.out.println("update.....");
    }

    public void query() {
        System.out.println("query.....");
    }
}

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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="defineClass" class="com.demo1.aop.log.DefineClass"></bean>
    <bean id="userService" class="com.demo1.aop.service.UserServiceImpl"></bean>

<!--方式二 自定义类-->
    <aop:config>
        <aop:aspect ref="defineClass">
            <aop:pointcut id="pointcut" expression="execution(* com.demo1.aop.service.UserServiceImpl.*(..))"></aop:pointcut>

            <aop:before method="before" pointcut-ref="pointcut"></aop:before>
            <aop:after method="after" pointcut-ref="pointcut"></aop:after>
        </aop:aspect>
    </aop:config>

</beans>


AOP实现方式三 注解方式

@Aspect
public class Stronger {

    @Before("execution(* com.demo1.aop.service.UserServiceImpl.*(..))")
    public void before() {
        System.out.println("before.....");
    }

    @After("execution(* com.demo1.aop.service.UserServiceImpl.*(..))")
    public void after() {
        System.out.println("after.....");
    }

    @Around("execution(* com.demo1.aop.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) {
        System.out.println("around前.....");
        try {
            Object proceed = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("around后.....");
    }


public class UserServiceImpl implements UserService {
    public void add() {
        System.out.println("add.....");
    }

    public void delete() {
        System.out.println("delete.....");
    }

    public void update() {
        System.out.println("update.....");
    }

    public void query() {
        System.out.println("query.....");
    }
}

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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="stronger" class="com.demo1.aop.log.Stronger"></bean>
    <bean id="userService" class="com.demo1.aop.service.UserServiceImpl"></bean>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

Spring整合Mybatis的依赖

 <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.0</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

Spring整合Mybatis的配置 以及声明式事务的配置


mybatis-config.xml的配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <setting name="logImpl" value="LOG4j"></setting>
    </settings>

    <typeAliases>
        <package name="com.transaction.pojo"></package>
    </typeAliases>

</configuration>
spring-dao.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:tx="http://www.springframework.org/schema/tx"
       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/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;userUnicode=true&amp;characterEncoding=UTF-8"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <property name="mapperLocations" value="classpath:com/transaction/dao/*.xml"></property>
    </bean>

<!--    <bean name="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
<!--        <constructor-arg name="sqlSessionFactory" ref="sessionFactory"/>-->
<!--    </bean>-->


<!--   spring中配置声明式事务-->
<!--    事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!--   结合AOP实现事务的通知-->
<!--    配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--        给那些方法配置事务-->
        <tx:attributes>
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="update" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="query" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

<!--    配置事务切入-->
    <aop:config>
        <aop:pointcut id="txPointcut" expression="execution(* com.transaction.dao.*.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"></aop:advisor>
    </aop:config>
</beans>

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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="spring-dao.xml"></import>

  <bean id="userMapper" class="com.transaction.dao.UserMapperImpl">
<!--      <property name="sqlSession" ref="sqlSession"></property>-->
      <property name="sqlSessionFactory" ref="sessionFactory"></property>
  </bean>
</beans>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值