spring4(二)

1、spring的IOC的注解开发

1-1 Spring的IOC的注解开发的入门

  1. 创建一个web项目引入相应的jar包

在spring4的版本中,除了引入基本的开发包以外,还需要引入aop包
https://pan.baidu.com/s/1kTLdmZ7QIaTxotMQ4xMwsQ

  1. 引入spring的配置文件

在src下创建一个applicationContext.xml
 引入约束:使用注解开发引入context约束
 spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
在文档的末尾找到 the context schema引入即可

<?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 -->
</beans>
  1. 配置组件扫描
    在applicationContext.xml文件下配置组件扫描
	<context:component-scan base-package="com.qgc.spring.demo1">
	</context:component-scan>
  1. 在类上添加注解
import org.springframework.stereotype.Component;

/**
 * 用户Dao的实现类
 * @author Administrator
 *
 */
@Component("userDao")	//这句话相当于<bean id="userDao" class="com.qgc.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
    
    
	
	@Override
	public void save() {
    
    
		System.out.println("方法执行了。。。。。");
	}
}
  1. 编写测试类
	@Test
	public void demo1() {
    
    
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao userDao = (UserDao) applicationContext.getBean("userDao");
		userDao.save();
	}
  1. 使用注解方式设置属性的值

使用注解方式设置属性的值可以没有set方法
 如果类中的属性有set方法,注解写在set方法上面
 如果类中没有set方法,那么注解写在属性的上面

@Component("userDao")	//这句话相当于<bean id="userDao" class="com.qgc.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
    
    
	@Value("林德德")
	private String name;
	
	public void setName(String name) {
    
    
		this.name = name;
	}
	@Override
	public void save() {
    
    
		System.out.println("方法执行了。。。。。"+name);
	}
}

1-2 spring的IOC注解的详解

@Component : 组件
 修饰一个类,将这个类交给Spring去管理
 这个注解有三个衍生注解(功能类似)
   @Controller : web层
   @Service : service层
   @Repository : dao层

属性注入的注解
 普通的属性
   @Value : 设置普通属性的值
 对象属性:
   @Autowired : 设置对象类型的属性的值,但是按照类型完成属性注入
    我们习惯按照名称完成属性注入,必须让@Autowired和@Qualifier一起使用完成名称属性注入
   @Resource : 完成对象类型的属性注入,并按照名称进行注入

@Service("userService")
public class UserServiceImpl implements UserService {
    
    
	@Resource(name = "userDao")
	private UserDao userdao;
	@Override
	public void save() {
    
    
		System.out.println("Service执行了。。。");
		userdao.save();
	}
}

生命周期注解(了解)
 @PostConstruct : 初始化方法
 @PreDestory : 销毁方法
Bean作用范围的注解
 @Scope :作用范围
  singleton :默认的,Spring会采用单例模式创建这个对象。
  prototype :多例模式。(Struts2和Spring整合一定会用到)

1-3 IOC的xml和注解开发的比较

enter description here
适用场景
 XML可以适用任何场景。
   结构清晰,维护方便
 注解:有些地方用不了,这个类不是自己提供的
   开发方便

1-4 XML和注解整合开发

XML管理Bean,注解完成属性注入

<!-- 在没有扫描的情况下使用属性注入的注解:@Resource、@Value等 -->
	<context:annotation-config/>

2、Spring的AOP的XML开发

2-1 AOP概述

  • 什么是AOP
    enter description here
    enter description here
    AOP:面向切面编程。AOP是OOP的扩展和延伸,解决OOP开发中遇到的问题。
  • Spring底层的AOP原理
    动态代理
      JDK动态代理 : 只能对实现了接口的类产生代理。
      Cglib动态代理(类似于javassist第三方技术):对没有实现接口的类产生代理对象,生成子类对象。

2-2 spring底层实现(了解)

2-2-1 JDK动态代理

public class jdkProxy implements InvocationHandler{
    
    
	private UserDao us;
	public jdkProxy(UserDao us) {
    
    
		this.us = us;
	}
	public UserDao createProxy() {
    
    
		UserDao userDao = (UserDao) Proxy.newProxyInstance(us.getClass().getClassLoader(), us.getClass().getInterfaces(), this);
		return userDao;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
		//判断方法是否为update
		if("update".equals(method.getName())){
    
    
			System.out.println("权限控制");
			return method.invoke(us, args);
		}
		return method.invoke(us, args);
	}
}

	@Test
	public void demo1() {
    
    
		UserDao userDao = new UserDaoImpl();
		UserDao userProxy = (UserDao) new jdkProxy(userDao).createProxy();
		userProxy.save();
		userProxy.update();
		userProxy.delete();
		userProxy.find();
	}

2-2-2 Cglib动态代理

enter description here

2-3 Spring的aop开发(AspectJ的XML方式)

2-3-1 AOP开发中相关的术语

enter description here

2-3-2 AOP开发入门

  1. 创建web项目引入jar包
  • 引入基本的开发包(6个)
  • 引入aop开发的jar包(4个)

https://pan.baidu.com/s/1K-bddZZ0mZuJNI84WH07iQ

  1. 引入Spring的配置文件

在src下创建一个applicationContext.xml
 引入约束:使用注解开发引入context约束
 spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
在文档的末尾找到 the aop schema引入即可

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->

</beans>
  1. 编写目标类并完成配置
<bean id="userDao" class="com.qgc.spring.demo2.UserDaoImpl"></bean>
  1. 编写测试类
  • spring与junit的整合

导入相应的包
https://pan.baidu.com/s/1AiHufJebkxC47o2p_ejaTw

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class springDemo3 {
    
    
	@Resource(name = "userDao")
	private UserDao userDao;
	@Test
	public void demo1() {
    
    
		userDao.save();
		userDao.delete();
	}
}
  1. 编写切面类
/**
 * 切面类
 * @author Administrator
 *
 */
public class MyAsceptXml {
    
    
	public void check() {
    
    
		System.out.println("==================权限校验==================");
	}
}
  1. 将切面类交给spring管理
	<bean id="myAscept" class="com.qgc.spring.demo2.MyAsceptXml"></bean>
  1. 通过AOP的配置实现增强
	<bean id="userDao" class="com.qgc.spring.demo2.UserDaoImpl"></bean>
	<bean id="myAscept" class="com.qgc.spring.demo2.MyAsceptXml"></bean>
	
	<aop:config>
		<!-- 表达式配置哪些类的哪些方法要进行增强 -->
		<aop:pointcut expression="execution(* com.qgc.spring.demo2.UserDaoImpl.delete(..))" id="p1"/>
		<!-- 配置切面 -->
		<aop:aspect ref="myAscept">
			<aop:before method="check" pointcut-ref="p1"/>
		</aop:aspect>
	</aop:config>

enter description here

2-3-3 Spring中通知的类型

  • 前置通知:在目标方法执行之前进行操作
    前置通知:获得切入点信息
<aop:aspect ref="myAscept">
			<aop:before method="check" pointcut-ref="p1"/>
</aop:aspect>
  • 后置通知:在目标函数执行之后进行操作
    获得方法的返回值
<!-- 后置通知 -->
			<aop:after-returning method="writeLog" pointcut-ref="p1" returning="aaaa"/>
public void writeLog(Object aaaa) {
    
    
		System.out.println("==========记录日志=========="+aaaa);
	}
  • 环绕通知,在目标方法执行之前和之后进行操作
    环绕通知可以阻止目标方法的执行
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    
    
		System.out.println("环绕通知前。。。。。");
		Object object = joinPoint.proceed();
		System.out.println("环绕通知后。。。。。");
		return object;
	}
<!-- 环绕通知 -->
	<aop:around method="around" pointcut-ref="p2"/>
  • 异常抛出通知:在程序出现异常的时候,进行的操作
  • 最终通知:无论代码是否有异常,总是会执行。

2-3-4 spring中切入点表达式的写法

语法
  [访问修饰符] 方法返回值 包名.类名.方法名(参数)
  +号代表子类

3、 Spring的AOP的基于AspectJ注解开发

3-1 AOP开发入门

  1. 创建web项目引入jar包
    引入基本的开发包(6个)
    引入aop开发的jar包(4个)

https://pan.baidu.com/s/1K-bddZZ0mZuJNI84WH07iQ

  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">
	
</beans>
  1. 编写目标类
<bean id="orderDao" class="com.qgc.spring.demo1.OrderDao"></bean>
  1. 编写切面类并配置
public class MyAscept {
    
    
	public void before() {
    
    
		System.out.println("前置增强。。。。。");
	}
}
<!-- 配置切面类 -->
	<bean id="myAscept" class="com.qgc.spring.demo1.MyAscept"></bean>
  1. 使用注解的AOP对象目标类进行增强
  • 在配置文件中打开注解的AOP开发
<aop:aspectj-autoproxy />
  • 在切面类上使用注解
@Aspect
public class MyAscept {
    
    
	@Before(value = "execution(* com.qgc.spring.demo1.OrderDao.find(..))")
	public void before() {
    
    
		System.out.println("前置增强。。。。。");
	}
}
  1. 编写测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class springDemo1 {
    
    
	@Resource(name = "orderDao")
	private OrderDao orderDao;
	@Test
	public void demo1() {
    
    
		orderDao.save();
		orderDao.delete();
		orderDao.find();
		orderDao.update();
	}
}

3-2 Spring的注解的AOP的通知类型

  • @Before :前置通知
    enter description here
  • @AfterReturning :后置通知
    enter description here
  • @Around :环绕通知
    enter description here

3-3 Spring的AOP的注解切入点的配置

@Aspect
public class MyAscept {
    
    
	@Before(value = "MyAscept.abc()")
	public void before() {
    
    
		System.out.println("前置增强。。。。。");
	}
	@Pointcut(value = "execution(* com.qgc.spring.demo1.OrderDao.find(..))")
	private void abc() {
    
    }
}

4、Spring的JDBC的模板的使用

Spring是EE开发的一站式的框架,有EE开发的每层的解决方案。Spring对持久层也提供了解决方案:ORM模块和JDBC的模板。
Spring提供了很多的模板用于简化开发:
enter description here

4-1 JDBC模板使用的入门

  1. 创建项目,引入jar包

引入基本开发包:(六个)
数据库驱动
Spring的JDBC模板的jar包(三个)
jdbc模板包:https://pan.baidu.com/s/1reNBYvhVrKk84_1-nppDLQ

  1. 创建数据库和表
create database spring4_day03;
use spring4_day03;
create table account(
	id int primary key auto_increment,
	name varchar(20),
	money double
);
  1. 使用JDBC模板保存数据
	@Test
	public void demo1() {
    
    
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://47.97.91.178/spring4_day03?useUnicode=true&amp;characterEncoding=UTF-8");
		dataSource.setUsername("qgc");
		dataSource.setPassword("2wsx@WSX");
		JdbcTemplate template = new JdbcTemplate(dataSource);
		template.update("insert into account values(null,?,?)","林德德",250d);
	}

4-2 将连接池和模板交给Spring管理

  1. 引入Spring的配置文件
	<bean id="driverManager" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql://47.97.91.178/spring4_day03"></property>
		<property name="username" value="qgc"></property>
		<property name="password" value="2wsx@WSX"></property>
	</bean>
	<bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="driverManager"></property>
	</bean>
  1. 使用Jdbc的模板

引入spring_aop的jar包

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext.xml")
public class jdbcDemo2 {
    
    
	@Resource(name = "jdbc")
	private JdbcTemplate template ; 
	@Test
	public void demo2() {
    
    
		template.update("insert into account values(null,?,?)","123",250d);
	}
}

4-3 使用开源的数据库连接池

  • DBCP的使用

引入dbcp的两个jar包
https://pan.baidu.com/s/1nFQBkDWeQuthTohha8R-hg

	<bean id="driverManager" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
		<property name="url" value="jdbc:mysql://47.97.91.178/spring4_day03"></property>
		<property name="username" value="qgc"></property>
		<property name="password" value="2wsx@WSX"></property>
	</bean>
	<bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="driverManager"></property>
	</bean>
  • C3P0的使用

引入c3p0的一个jar包
https://pan.baidu.com/s/1uzyLi2LzkYohIGJZI-CtkA

	<bean id="driverManager" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql://47.97.91.178/spring4_day03"></property>
		<property name="user" value="qgc"></property>
		<property name="password" value="2wsx@WSX"></property>
	</bean>
	<bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="driverManager"></property>
	</bean>

4-4 抽取配置到属性文件

  1. 定义一个属性文件
#jdbc.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://47.97.91.178/spring4_day03
jdbc.username=qgc
jdbc.password=2wsx@WSX
  1. 在Spring的配置文件中引入属性文件
  • 第一种方式(不常用)
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location" value="classpath:jdbc.properties"></property>
</bean>
  • 第二种方式
<context:property-placeholder location="classpath:jdbc.properties"/>
  1. 引入属性文件的值

格式:${properties文件中的key值}

<bean id="driverManager" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="${jdbc.driverClass}"/>
		<property name="url" value="${jdbc.url}"></property>
		<property name="username" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>

4-5 使用JDBC的模板完成CRUD的操作

  • 查询操作
    enter description here
  • 查询返回对象或集合
    enter description here
  • 数据封装
    enter description here

5、Spring的事务管理

5-1 Spring的事务管理的API

5-1-1 PlatformTransactionManager:平台事务管理器

平台事务管理器:接口,是Spring用于管理事务的真正的对象。
  DataSourceTransactionManager :底层使用JDBC管理事务
  HibernateTransactionManager :底层使用Hibernate管理事务

5-1-2 TransactionDefinition :事务定义信息

事务定义:用于定义事务的相关的信息,隔离级别、超时信息、传播行为、是否只读

5-1-3 TransactionStatus:事务的状态

事务状态:用于记录在事务管理过程中,事务的状态的对象。

5-1-4 事务管理的API的关系:

Spring进行事务管理的时候,首先平台事务管理器根据事务定义信息进行事务的管理,在事务管理过程中,产生各种状态,将这些状态的信息记录到事务状态的对象中。

5-2 Spring的事务的传播行为

enter description here
Spring中提供了七种事务的传播行为:

保证多个操作在同一个事务中
PROPAGATION_REQUIRED :默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来
 PROPAGATION_SUPPORTS :支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
 PROPAGATION_MANDATORY :如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。

保证多个操作不在同一个事务中
PROPAGATION_REQUIRES_NEW :如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作。
 PROPAGATION_NOT_SUPPORTED :如果A中有事务,将A的事务挂起。不使用事务管理。
 PROPAGATION_NEVER :如果A中有事务,报异常。

嵌套式事务
 PROPAGATION_NESTED :嵌套事务,如果A中有事务,按照A的事务执行,执行完成后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始位置,也可以回滚到保存点。

5-3 搭建Spring的事务管理的环境

  1. 创建Service的接口和实现类
public class AccountServiceImpl implements AccountService {
    
    
	private AccountDao accountDao;
	
	public void setAccountDao(AccountDao accountDao) {
    
    
		this.accountDao = accountDao;
	}
	
	@Override
	public void transfer(String from, String to, Double money) {
    
    
		
		accountDao.outMoney(from, money);
		int i = 1/0;
		accountDao.inMoney(to, money);
//		System.out.println(accountDao);
	}

}
  1. 在DAO中编写扣钱和加钱方法:
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    
    

	@Override
	public void outMoney(String from, Double money) {
    
    
		// TODO Auto-generated method stub
		this.getJdbcTemplate().update("update account set money = money - ? where name = ?",money,from);
	}

	@Override
	public void inMoney(String to, Double money) {
    
    
		// TODO Auto-generated method stub
		this.getJdbcTemplate().update("update account set money = money + ? where name = ?",money,to);
	}
}
  1. 配置连接池和JDBC的模板
	<!-- 配置连接池和JDBC的模板 -->
	<!-- 第二种方式通过context标签引入的 -->
	<context:property-placeholder location="classpath:jdbc.properties"/>
	
	<!-- 配置C3P0连接池=============================== -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"/>
		<property name="jdbcUrl" value="${jdbc.url}"/>
		<property name="user" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
  1. 在DAO注入Jdbc的模板

dao的实现类继承JdbcDaoSupport类,底层就提供了dataSource的set方法,所以不用再写
JdbcDaoSupport的底层也提供了jdbcTemplate的set方法

<!-- 配置DAO================= -->
	<bean id="accountDao" class="com.qgc.tx.demo1.AccountDaoImpl">
		<property name="dataSource" ref="dataSource"/>
	</bean>
  1. 在service层注入dao实现类

注意service要提供出注入属性的set方法

<bean id="accountService" class="com.qgc.tx.demo1.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"/>
</bean>

5-4 Spring的事务管理:一类:编程式事务(需要手动编写代码)

  1. 第一步:配置平台事务管理器
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
  1. 第二步:Spring提供了事务管理的模板类
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="transactionManager"></property>
</bean>
  1. 第三步:在业务层注入事务管理的模板
	<bean id="accountService" class="com.qgc.tx.demo1.AccountServiceImpl">
		<property name="accountDao" ref="accountDao"/>
		<property name="transactionTemplate" ref="transactionTemplate"></property>
	</bean>
  1. 编写事务管理的代码
	private TransactionTemplate transactionTemplate;
	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
    
    
		this.transactionTemplate = transactionTemplate;
	}
	@Override
	public void transfer(String from, String to, Double money) {
    
    
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    
    
			
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
    
    
				accountDao.outMoney(from, money);
//				int i = 1/0;
				accountDao.inMoney(to, money);
//				System.out.println(accountDao);
				
			}
		});
	}

5-5 二类:声明式事务管理(通过配置实现)—AOP

5-5-1 XML方式的声明式事务管理

  1. 第一步:引入aop的开发包
  2. 第二步:配置事务管理器
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
  1. 第三步:配置增强
	<tx:advice transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="transfer" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
  1. 第四步:AOP的配置
	<aop:config>
		<aop:pointcut expression="execution(* com.qgc.tx.demo1.AccountServiceImpl.*(..))" id="pointcut1"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
	</aop:config>

5-5-2 注解方式的声明式事务管理

  1. 第一步:引入aop的开发包
  2. 第二步:配置事务管理器
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
  1. 第三步:开启注解事务
<tx:annotation-driven transaction-manager="transactionManager"/>
  1. 第四步:在业务层添加注解
@Transactional
public class AccountServiceImpl implements AccountService {
    
    
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
    
    
		this.accountDao = accountDao;
	}

猜你喜欢

转载自blog.csdn.net/m_awdawdw/article/details/103501240
今日推荐