Spring学习笔记(四)

目录

十二.10、Spring之数据访问

12.1、Spring数据访问工程环境搭建

在这里插入图片描述
导入需要的jar包

commons-logging-1.1.3.jar
druid-1.1.9.jar
mysql-connector-java-5.1.37-bin.jar
spring-aop-4.3.18.RELEASE.jar
spring-beans-4.3.18.RELEASE.jar
spring-context-4.3.18.RELEASE.jar
spring-core-4.3.18.RELEASE.jar
spring-expression-4.3.18.RELEASE.jar
spring-jdbc-4.3.18.RELEASE.jar
spring-orm-4.3.18.RELEASE.jar
spring-test-4.3.18.RELEASE.jar
spring-tx-4.3.18.RELEASE.jar

配置jdbc.properties

user=root
password=root
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
initialSize=5
maxActive=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"
	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-4.3.xsd">
	
	<!-- 包扫描 -->
	<context:component-scan base-package="com.atguigu"></context:component-scan>
	<!-- 加载jdbc.properties属性配置文件 -->
	<context:property-placeholder location="classpath:jdbc.properties"/>
	<!-- 配置数据源 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<property name="username" value="${user}" />
		<property name="password" value="${password}" />
		<property name="driverClassName" value="${driverClassName}" />
		<property name="url" value="${url}" />
		<property name="initialSize" value="${initialSize}" />
		<property name="maxActive" value="${maxActive}" />
	</bean>

</beans>

测试的代码:

@ContextConfiguration(locations="classpath:applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringTest {

	@Autowired
	DataSource dataSource;
	
	@Test
	public void testDataSource() throws Exception {
		System.out.println( dataSource.getConnection() );
	}
	
}


12.2、Spring之JdbcTemplate使用

在Spring中提供了对jdbc的封装类叫JdbcTemplate。它可以很方便的帮我们执行sql语句,操作数据库。

先准备单表的数据库数据

drop database if exists jdbctemplate;
create database jdbctemplate;
use jdbctemplate;

CREATE TABLE `employee` (
  `id` int(11) primary key AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `salary` decimal(11,2) DEFAULT NULL
);

insert  into `employee`(`id`,`name`,`salary`) 
values (1,'李三',5000.23),(2,'李四',4234.77),(3,'王五',9034.51),
(4,'赵六',8054.33),(5,'孔七',6039.11),(6,'曹八',7714.11);

select * from employee;

JdbcTemplate的使用需要在applicationContext.xml中进行配置


<!-- jdbcTemplate -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource"  ref="dataSource"/>
	</bean>

实验2:将id=5的记录的salary字段更新为1300.00

@Test
	public void test2() throws Exception {
		String sql = "update employee set salary = ? where id = ?";
		// update方法执行insret、update、delete语句
		jdbcTemplate.update(sql,new BigDecimal(1300),5);
	}

实验3:批量插入

@Test
	public void test3() throws Exception {
		String sql = "insert into employee(`name`,`salary`) values(?,?)";
		/**
		 * 一条sql语句参数是一个一维数组,那么多条sql语句,它的参数是多个一维数组
		 */
		List<Object[]> batchArgs = new ArrayList<Object[]>();
		
		batchArgs.add(new Object[] {"飞龙",new BigDecimal(99999)});
		batchArgs.add(new Object[] {"英哥",new BigDecimal(9999)});
		batchArgs.add(new Object[] {"国哥",new BigDecimal(999)});
		
		jdbcTemplate.batchUpdate(sql, batchArgs);
	}


实验4:查询id=5的数据库记录,封装为一个Java对象返回

创建Employee对象

public class Employee {
	private Integer id;
	private String name;
	private BigDecimal salary;

测试代码:

@Test
	public void test4() throws Exception {
		String sql = "select id,name,salary from employee where id = ?";
		/**
		 * 第一个参数是sql语句<br/>
		 * RowMapper接口,它的实现类可以帮我们把查询到的resultSet每一行记录封装成为javaBean返回
		 */
		Employee employee = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Employee>(Employee.class), 5);
		System.out.println(employee);
	}

实验5:查询salary>4000的数据库记录,封装为List集合返回

@Test
	public void test5() throws Exception {
		String sql = "select id,name,salary from employee where salary > ?";
		/**
		 * 查询一行记录使用queryForObject。<br/>
		 * 查询多行记录,使用query方法
		 */
		jdbcTemplate.query(sql, new BeanPropertyRowMapper<Employee>(Employee.class), new BigDecimal(4000))
				.forEach(System.out::println);
	}

实验6:查询最大salary

// 实验6:查询最大salary
	@Test
	public void test6() throws Exception {
		String sql = "select max(salary) from employee";
		BigDecimal salary = jdbcTemplate.queryForObject(sql, BigDecimal.class);
		System.out.println( salary );
	}

实验7:使用带有具名参数的SQL语句插入一条员工记录,并以Map形式传入参数值

配置applicationContext.xml配置文件:


<!-- 配置可以执行命名参数sql语句的 NamedParameterJdbcTemplate -->
	<bean id="namedParameterJdbcTemplate" 
		class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
		<constructor-arg index="0" ref="dataSource" />
	</bean>

测试代码:

@Test
	public void test7() throws Exception {
		/**
		 * :name 相当于 ? 占位符,name就是这个参数的名称
		 */
		String sql = "insert into employee(`name`,`salary`) values(:name,:salary)";
		
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("name", "我是命名(具名)参数的");
		paramMap.put("salary", new BigDecimal(1234));
		
		namedParameterJdbcTemplate.update(sql, paramMap);
	}

实验8:重复实验7,以SqlParameterSource形式传入参数值

// 实验8:重复实验7,以SqlParameterSource形式传入参数值
	@Test
	public void test8() throws Exception {
		/**
		 * :name 相当于 ? 占位符,name就是这个参数的名称
		 */
		String sql = "insert into employee(`name`,`salary`) values(:name,:salary)";
		
		Employee employee = new Employee(null, "我是具名参数插入的", new BigDecimal(30000));
		
		/**
		 * SqlParameterSource给sql语句传入需要的参数值
		 */
		namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(employee));
	}

实验9:创建Dao,自动装配JdbcTemplate对象

创建EmployeeDao :

@Repository
public class EmployeeDao {

	@Autowired
	JdbcTemplate jdbcTemplate;

	public int saveEmployee(Employee employee) {
		return jdbcTemplate.update("insert into employee(`name`,`salary`) values(?,?)", employee.getName(),
				employee.getSalary());
	}
}


测试代码:

@Test
	public void test9() throws Exception {
		Employee employee = new Employee(null, "我是Dao插入的", new BigDecimal(1234));
		employeeDao.saveEmployee(employee);
	}


实验10:通过继承JdbcDaoSupport创建JdbcTemplate的Dao


@Repository
public class EmployeeDao extends JdbcDaoSupport{

//	@Autowired
//	JdbcTemplate jdbcTemplate;

	@Autowired
	public void initJdbcTemplate(DataSource dataSource) {
		setDataSource(dataSource);
	}

	public int saveEmployee(Employee employee) {
		return getJdbcTemplate().update("insert into employee(`name`,`salary`) values(?,?)", employee.getName(),
				employee.getSalary());
	}
}

测试代码:

@Test
	public void test10() throws Exception {
		Employee employee = new Employee(null, "我是JdbcDaoSupport插入的", new BigDecimal(1234));
		employeeDao.saveEmployee(employee);
	}


十三、声明式事务

事务分为声明式和编程式两种:
声明式事务:声明式事务是指通过注解的形式对事务的各种特性进行控制和管理。
编码式(编程式)事务:指的是通过编码的方式实现事务的声明。

13.0 事务回顾

13.0.0 事务的概念

事务:指逻辑上的一组操作,组成这组操作的各人但愿,要么全部成功,要么全部不成功。从而确保了数据的准确和安全。

下面以一个案例说明:

  • 例如:A——B转帐,对应于如下两条sql语句:
/*转出账户减钱*/
 update account set money=money-100 where name=‘a’;
 /**转⼊账户加钱*/
 update account set money=money+100 where name=‘b’;

13.0.2 事务的四大特性

  1. 原子性(Atomucity):原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
    这是 :从操作的角度来描述,事务中的各个操作要么都成功要么都失败。
  2. 一致性(Consistency):事务必须是数据库从一个一致性状态变换到另一个一致性状态。
    例如:转账前A 有 1000 ,B有1000 。转账后A+B 也得是 2000.
    这是:从数据的角度来说的,(1000,1000) (900,1100) ,不应该出现 ( 900,1000)的情况 )
  3. 隔离性(Isolation)事务的隔离性 是多个用户并发访问数据库时,数据库为每一个用户开启的事务,每个事务不能被其他事务的操作数据所干扰,多个并发事务之前要互相隔离。
    比如:事务1给员工涨工资 2000,但是事务1尚未被提交,员工发起事务2查询工资,发现工资涨了2000块钱,读到了事务1尚未提交的数据(脏读)。
  4. 持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中的数据的改变就是永久性的,接下来即使发生故障也不应该对齐有任何影响。

13.0.3 事务的隔离级别

不考虑隔离级别,会出现以下错误的情况:也即在隔离级别在解决事务并发问题

  • 脏读: 一个事务读到另一个线程中未提交的数据

    场景:
    比如:事务1给员工涨工资 2000,但是事务1尚未被提交,员工发起事务2查询工资,发现工资涨了 2000块钱,读到了事务1尚未提交的数据(脏读)。

  • 不可重复读:一个线程中 的事务读到了另一个线程中已经提交的update 的数据(前后内容不一样)

    场景:
    员工A发起事务1,查询工资,工资为1w ,此时 事务1尚未关闭。
    财务人员发起了事务2,给员工A涨了 2000 块钱,并且提交了事务
    员工A通过事务1再次发起查询请求,发现工资为1.2w,原来读出来1w 读不到了,叫做不可重复读。

  • 虚读(幻读):一个线程中的事务读到了另一个线程中已经提交的insert或者delete的数据(前后条数不一样)

    场景:
    事务1、查询所有工资为1w 的员工的总数,查询出来了10个人,此时事务尚未关闭
    事务2 、财务人员发起,新来员工,工资1w,向表中插入2条数据,并且提交了事务。
    事务1、再次查询工资为1w 的员工个数,发现有 12个人。

13.0.4 数据库共定义了四种隔离级别

  • Serializable(串行化):
    可避免脏读,不可重复读,虚读情况的发生。隔离最高

  • Repeatable read(可重复读):
    可避免脏读,不可重复读情况的发生。(幻读有可能发生) 隔离级别第二高
    该机制下会对要update的行进行加锁,避免了不可重复读de 情况。

  • Read committed (读已提交) :可避免脏读情况发生。不可重复读和幻读一定会发生。隔离级别第三

  • Read uncommitted(读为提交):最低级别,以上情况均无法保证。隔离级别最低
    注意:级别依次升⾼,效率依次降低

  • MySql 的默认隔离级别是:Repeatable read

  • 查询当前使⽤的隔离级别:select @@tx_isolation;

  • 设置MySQL事务的隔离级别:set session transaction isolation level xxx;(设置的是当前
    mysql连接会话的,并不是永久改变的)

13.1、编码方式实现事务

在这里插入图片描述

13.2、声明式事务环境搭建

13.2.1、准备测试数据库

##创建tx数据库
drop database if exists `tx`;
CREATE database `tx`;
##切换tx数据库
USE `tx`;

##删除用户表
DROP TABLE IF EXISTS `user`;
##创建用户表
CREATE TABLE `user` (
  `id` int primary key auto_increment,	
  `username` varchar(50) NOT NULL,
  `money` int(11) DEFAULT NULL
);
##插入数据
insert  into `user`(`username`,`money`) values ('张三',1000),('李四',1000);

##删除图书表
drop table if exists `book`;
##创建图书表
create table `book`(
    `id` int primary key auto_increment,
    `name` varchar(500) not null,
    `stock` int
);
##插入数据
insert into book(`name`,`stock`) values('java编程思想',100),('C++编程思想',100);

##查看数据
select * from book;
select * from user;

13.2.2、创建一个Java工程,导入Jar包

在这里插入图片描述
拷贝原来的Spring-jdbcTemplate工程

dao的代码


@Repository
public class BookDao {

	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	public void updateBook() {
		jdbcTemplate.update("update book set name = '图书表被修改了'");
	}
	
}

@Repository
public class UserDao {

	@Autowired
	JdbcTemplate jdbcTemplate;

	public void updateUser() {
		jdbcTemplate.update("update user set username='用户表被修改了'");
	}

}

Service的代码:

@Service
public class TransactionService {

	@Autowired
	private UserDao userDao;
	
	@Autowired
	private BookDao bookDao;
	
	public void multiUpdate() {
		userDao.updateUser();
		
		bookDao.updateBook();
	}
	
}

13.3、测试Service的默认事务

正常情况下


public class SpringTest {

	@Test
	public void test1() throws Exception {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		TransactionService transactionService = (TransactionService) applicationContext.getBean("transactionService");
		transactionService.multiUpdate();
	}

}

  • 异常的演示
    修改TransactionService中的方法
    在这里插入图片描述
    最后的结果是:

用户表被修改了:
在这里插入图片描述
而图书表没有被修改:
在这里插入图片描述

Spring事务引入的分析------PlatformTransactionManager类简单介绍

PlatformTransactionManager接口是Spring提供用来管理事务的统一接口。

PlatformTransactionManager的实现类

在这里插入图片描述
Spring事务底层管理原理:
在这里插入图片描述

13.4、使用Spring的注解声明事务管制

实验2:测试Spring的声明式事务

给类或方法添加注解:


	/**
	 * 表示此方法支持事务
	 */
	@Transactional
	public void multiUpdate() {
		userDao.updateUser();
		int i = 12 / 0;
		bookDao.updateBook();
	}

applicationContext.xml中的配置:

<!-- 配置事务管理器
			事务管理器id一般只叫:transactionManager。
	 -->
	<bean id="transactionManager" 
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<!-- 这里的数据源一定是访问数据库时用的同一个数据源 -->
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- tx:annotation-driven 标签表示支持@Transactional注解声明式事务
			而且会自动代理
			transaction-manager="transactionManager" 表示使用哪个事务管理器
			如果事务管理器的id值是:transactionManager,此属性可以省略
	 -->
	<tx:annotation-driven />

13.5、noRollbackFor和noRollbackForClassName测试不回滚的异常

实验3:noRollbackFor和noRollbackForClassName测试不回滚的异常

/**
	 * 表示此方法支持事务<br/>
	 * 	默认情况下是RunTimeException运行时和它的子异常。会回滚事务<br/>
	 * 	
	 * noRollbackFor=ArithmeticException.class表示设置算术异常不回滚 <br/>
	 * noRollbackForClassName="java.lang.ArithmeticException" 设置指定全类名的异常不回滚事务
	 */
	@Transactional(noRollbackForClassName="java.lang.ArithmeticException")
	public void multiUpdate() {
		userDao.updateUser();
		int i = 12 / 0;
		bookDao.updateBook();
	}


13.6、自定义设置回滚异常

实验5:rollbackFor和rollbackForClassName回滚的异常


/**
	 * 表示此方法支持事务<br/>
	 * 	默认情况下是RunTimeException运行时和它的子异常。会回滚事务<br/>
	 * 	rollbackFor=FileNotFoundException.class 表示设置文件未找到异常也回滚事务<br/>
	 * rollbackForClassName="java.io.FileNotFoundException" 表示设置的全类名的异常回滚事务
	 */
	@Transactional(rollbackForClassName="java.io.FileNotFoundException")
	public void multiUpdate() throws FileNotFoundException {
		userDao.updateUser();
		int i = 0; 
		if (i == 0) {
			throw new FileNotFoundException();
		}
		bookDao.updateBook();
	}

13.7、事务的只读属性

实验4:测试readOnly只读属性

/**
	 * 表示此方法支持事务<br/>
	 * 	默认情况下是RunTimeException运行时和它的子异常。会回滚事务<br/>
	 *  readOnly属性设置当前方法是否允许更新数据库
	 *  	默认值是false,表示允许执行insert、delete、update语句
	 *  	readOnly=true,表示不允许执行insert、delete、update语句
	 */
	@Transactional(readOnly=true)
	public void multiUpdate() throws FileNotFoundException {
		userDao.updateUser();
//		int i = 0; 
//		if (i == 0) {
//			throw new FileNotFoundException();
//		}
		bookDao.updateBook();
	}


报的异常

在这里插入图片描述

13.8、事务超时属性timeout(秒为单位)

	/**
	 * 表示此方法支持事务<br/>
	 * 默认情况下是RunTimeException运行时和它的子异常。会回滚事务<br/>
	 * timeout=3 表示3秒后不允许再执行sql语句。
	 */
	@Transactional(timeout = 3)
	public void multiUpdate() throws Exception {
		userDao.updateUser();
		Thread.sleep(4000);
		bookDao.updateBook();
	}

事务超时报如下异常:
在这里插入图片描述

13.10、事务的传播特性propagation

  • 什么是事务的传播行为:
    当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。
    事务的传播行为可以由传播属性指定。Spring定义了7种类传播行为。

  • 事务的传播特性,有以下几种类型:

在这里插入图片描述

13.11、注解演示事物传播特性

UserService
BookService
TransactionService

实验1:大小事务传播特性都是REQUIRED


@Transactional(propagation = Propagation.REQUIRED)
	public void multiTransaction() {
	@Transactional(propagation = Propagation.REQUIRED)
	public void updateBook() {
@Transactional(propagation=Propagation.REQUIRED)
public void updateUser() {


在这里插入图片描述
只要所有代码都没有异常。那么所有操作都将成功
只要有代码产生异常。那么所有操作都将失败。

实验2:大小事务传播特性都是REQUIRES_NEW


@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void multiTransaction()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateBook()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateUser()


在这里插入图片描述

实验3:大事务是REQUIRED,小事务都是REQUIRES_NEW


@Transactional(propagation = Propagation.REQUIRED)
	public void multiTransaction()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateBook()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateUser()

在这里插入图片描述

实验4:大事务是REQUIRED,小1REQUIRED,小2REQUIRES_NEW

@Transactional(propagation = Propagation.REQUIRED)
	public void multiTransaction()
	@Transactional(propagation = Propagation.REQUIRED)
	public void updateBook()
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateUser()

在这里插入图片描述

14、xml配置式事务声明

1、拷贝刚刚的Spring-tx-annotation工程改为Spring-tx-xml(xml方式配置声明式事务)
2、记得去掉代码中所有@Transactional的注解。

<?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 http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

	<!-- 包扫描 -->
	<context:component-scan base-package="com.atguigu"></context:component-scan>
	<!-- 加载jdbc.properties属性配置文件 -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<!-- 配置数据源 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<property name="username" value="${user}" />
		<property name="password" value="${password}" />
		<property name="driverClassName" value="${driverClassName}" />
		<property name="url" value="${url}" />
		<property name="initialSize" value="${initialSize}" />
		<property name="maxActive" value="${maxActive}" />
	</bean>

	<!-- 配置Spring提供用来访问数据库的类JdbcTemplate -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	
<!-- 	事务由:AOP + 切面(事务管理器) + 事务属性 -->
	<bean id="transactionManager" 
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	
	<!-- 配置事务属性 -->
	<tx:advice id="tx_advice" transaction-manager="transactionManager">
		<!-- 配置事务属性 -->
		<tx:attributes>
			<!-- 
				方法在匹配事务属性规则的时候,匹配顺序是:精确匹配====>>>半模糊====>>>全模糊
			 -->
			<!-- 
				tx:method 标签给某些方法配置事务属性
					name属性设置方法名
					propagation="REQUIRED"表示有事务
				
				精确匹配 -->
			<tx:method name="updateUser" propagation="REQUIRED"/>
			<!-- 
				半模糊匹配
				name="save*" 表示以save打头的方法,都匹配上
			 -->
			<tx:method name="save*" propagation="REQUIRED"/>
			<!-- 
				半模糊匹配
				name="update*" 表示以update打头的方法,都匹配上
			 -->
			<tx:method name="update*" propagation="REQUIRES_NEW"/>
			<!-- 
				name="delete*" 表示以delete打头的方法,都匹配上
			 -->
			<tx:method name="delete*" propagation="REQUIRED"/>
			
			<tx:method name="multiUpdate" propagation="REQUIRES_NEW"/>
			<tx:method name="multiTransaction" propagation="REQUIRED"/>
			
			<!-- 
				name="*" 表示剩下的方法
				read-only="true" 底层会做一些事务优化

				全模糊
			 -->
			<tx:method name="*" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 配置事务需要的aop(代理) -->
	<aop:config>
		<aop:advisor advice-ref="tx_advice" pointcut="execution(public * com.atguigu..*Service.*(..))"/>
	</aop:config>

</beans>

15、Spring整合Web

15.1、在web工程中添加Spring的jar包。

  • Spring的核心包
    spring-beans-4.0.0.RELEASE.jar
    spring-context-4.0.0.RELEASE.jar
    spring-core-4.0.0.RELEASE.jar
    spring-expression-4.0.0.RELEASE.jar
  • aop包
    spring-aop-4.0.0.RELEASE.jar
    spring-aspects-4.0.0.RELEASE.jar
    com.springsource.org.aopalliance-1.0.0.jar
    com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
  • JDBC-ORM包
    spring-jdbc-4.0.0.RELEASE.jar
    spring-orm-4.0.0.RELEASE.jar
    spring-tx-4.0.0.RELEASE.jar
  • Spring的web整合包
    spring-web-4.0.0.RELEASE.jar
  • 测试包
    spring-test-4.0.0.RELEASE.jar

整合Spring和Web容器分两个步骤:

1、导入spring-web-4.0.0.RELEASE.jar
2、在web.xml配置文件中配置org.springframework.web.context.ContextLoaderListener监听器监听ServletContext的初始化
3、在web.xml配置文件中配置contextConfigLocation上下文参数。配置Spring配置文件的位置,以用于初始化Spring容器

在web.xml中配置

获取WebApplicationContext上下文对象的方法如下:

方法一(推荐):
WebApplicationContextUtils.getWebApplicationContext(getServletContext())

方法二(不推荐):
getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值