第一天:spring概念和ioc入门(ioc操作xml配置文件)
第二天:spring的ioc操作(注解)和aop概念
第三天:jdbcTemplate和spring事务管理(之前用hibernate)
第四天:ssh框架整合开发
day01
一、 spring概念
-
开源的轻量级框架(不依赖很多其他东西–轻量级)
-
两部分核心
- aop 面向切面编程,扩展功能不是修改源代码来实现
- ioc 控制反转,把对象的创建交给spring,通过配置代替之前的new对象操作。
- 一站式框架
在javaee三层结构中,每一层都提供了不同的解决技术
web层:springMVC
service层:spring的ioc
dao层:spring的jdbcTemplate
版本:
hibernate5.x
struts2
spring4.x
二、IOC底层原理
1)分析:
思想:高内聚,低耦合
按之前生成对象的方式,new User(),如果User类发生了改动,那么它使用的所有地方都需要修改。耦合度太高。
后来出现了工厂模式,每次创建调用工厂。这样降低了一些耦合度,不过工厂和对象出现了新的耦合。
2) ioc底层原理
用到了四种技术
(1)xml配置文件
(2)dom4j 解析xml
(3)工厂设计模式
(4)反射
步骤如下:
好处:
如果Service对象发生了改变,那么我们不需要在其他地方改动代码。
如果Service对象路径发生了改变,那么我们只需修改xml配置文件。
耦合度大大减少
三、ioc入门案例
第一步:导入jar包
第二步: 创建类,在类里面创建方法
第三步:创建配置文件,配置创建的类
(1)核心配置文件名称和位置不固定,但是建议放到src下,官方建议起名applicationContext.xml
(2)引入约束schema
第四步: 创建文件测试
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
User user = (User) context.getBean("user");
System.out.println(user);
user.add();
结果:成功读取到对象并调用方法
四、spring的bean管理(xml配置文件)
1、bean实例化的三种方式
第一种:使用类的无参构造(重点)
第二种:使用静态工厂(麻烦,不用)
创建静态方法返回类的对象
调用:
Bean2Factory.getBean2();
第三种:使用实例工厂创建(麻烦,不用)
创建非静态方法,用工厂类的对象去返回
2、第一种创建方式的常用属性
- id:起的名称,任意命名(不能包含特殊符号,根据id值得到配置对象)
- class:创建的类所在的路径
- name:和id属性一样,可以包含特殊符号(一般不用)
- scope:重要,会用前两个即可
singleton:创建的对象指向同一个。
prototype与之相反。
五、属性注入
概念
希望在创建对象时,能初始化属性的值。
spring只支持前两种,用的最多的是第一种。
在spring中的两种实现
第一种:有参构造
第一步:创建实体类
第二步:在xml中进行配置
第二种:set
第一步:创建实例,包含所需注入的属性,和属性的set方法
第二步:配置文件,对Book类进行属性注入
六、注入的属性是对象类型(重要)
Service类包括一个对象成员,用set属性注入的方式实现得到Service对象,成员对象dao也一带创建。
七、P名称空间注入(少用)
1、引入名称空间
2、注入
八、spring注入复杂数据
- 数组
- list 集合
- map 集合
- properties 类型
在java代码中完成数据成员的声明,和set方法。在配置文件中把这些放到 < bean >里面
八、IOC和DI的区别
IOC:控制反转,把对象创建交给spring进行配置
DI:依赖注入,向类里面的属性设置值(完成在对象创建之后)
因此DI是在IOC的基础至少完成
九、Spring整合项目的底层原理
解决问题:加载spring核心配置文件很耗时
实现思想:加载配置文件和创建对象的过程在服务器启动的时候完成。
底层实现原理:
服务器启动的时候,会给每个项目创建一个ServletContext对象。我们用监听器(ServletListener)监听创建的时候,我们在这个时候做一些事
-
加载sring核心配置文件,创建相关的对象
-
把创建出来的对象,存入ServletContext域对象中
-
使用的时候再取出来
spring把这些封装好了
day02
1、spring的bean管理(IOC的注解方式实现)
2、AOP深层分析
3、sring的AOP演示
4、log4j警告信息介绍
5、spring整个web项目具体操作
一、注解
@注解名称(属性名称=属性值)
可以使用在类上面,方法上面和属性上面
1.1 准备工作
第一天引入的约束是beans的约束
现在做注解开发,需要再引入一个新的约束。
<?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>
然后开启注解的扫描,让spring知道扫描哪些包上面的类、属性、方法的注解
1.2 注解创建对象
等价于day01的bean写法
另外还有几个注解
就目前而言,他们的功能是一致的
规定是单实例还是多实例(多实例可以用于action)
1.3 注入属性
还是day01的需求。
第一步:创建dao和service对象
第二步:引入成员对象
不需要写set方法
另一种注释法:
Resource(name=“userDao”),name里面的值填的是Dao类在value里写的值
调用的话,还是之前的context.getBean(“你在value的值”);
二、配置和注解的方式可以结合
创建对象用配置文件
在属性中用注释(注意,也要提前引包)
12/4号 个人总结
今天是学spring的第二天,第一天领进门。
今天学习的内容是 通过两种方式,创建对象。
一种是在bean标签里面标记,在类里面生成该成员的set方法,在bean里面的proper添加属性,完成属性注入(对象注入用ref)。
另一种是注解,前提是在配置文件中,引入要扫描的包。然后在类中添加注释(负责对象的创建),在属性上添加注释(属性注入)
重点还是要掌握底层,ioc的实现原理(后面写一个小案例),记过多的轮子用处不大。
三、AOP深入分析
概念
struts2拦截器的时候学到了,拓展功能不修改源代码。这只是通俗理解。
AOP采用横向抽取机制,取代了传统的纵向继承机制(听不懂~)
图解纵向机制的发展
横向抽取机制
底层:动态代理方式,推送自己的博客
至此,阐述了AOP的底层原理,底层代码待学完轮子后再补上(挖个坑)
四、AOP操作术语
假设现在有这么一个类需要被增强
1、连接点JoinPoint:类里面的哪些方法可以被增强,那么这些方法就称为连接点。
add、delete、findAll和update
2、切入点Pointcut(重点):类里面有很多的方法可以被增强,但是我们仅仅增强其中几个。
例如仅仅增强add和update,那么这两个就称为切入点
3、通知或增强Advice(重要):增强切入点,是个动宾结构
比如拓展一个日志的功能,那么这就叫增强。
- 前置通知:在方法之前执行
- 后置通知:在方法之后执行
- 异常通知:
- 最终通知:
- 环绕通知:方法之前和之后执行
4、切面Aspect(重要):把增强用到切入点,把增强应用到具体方法的过程
例如把日志功能用到add(),这个过程就叫切面
5、其他,了解即可
五、spring里的aop操作(Aspectj)
使用aspectj实现aop有两种方式
准备工作
导入jar包
创建spring的核心配置文件,导入aop的约束
<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">
第一种方式:配置文件
案例: 希望在Book的add之前,先执行Mybook的add
public class Book {
public void add() {
System.out.println("add....");
}
}
public class MyBook {
public void before1() {
System.out.println("前置增强...");
}
}
使用表达式配置切入点
切入点:被增强的方法,这里是add()
常用的表达式:
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
(1) execution(* cn.itcast.aop.Book.add(…)) // 对add进行增强
(2) execution(* cn.itcast.aop.Book.*(…)) //对所以的方法进行增强
(3) execution(* .(…))
(4) execution(* save*(…) // 匹配所以save开头的方法
具体配置
<?xml version="1.0" encoding="UTF-8" ?>
<!--引入schema约束-->
<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">
<!--1、生成对象-->
<bean id="book" class="cn.itcast.aop.Book"></bean>
<bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
<!--2、配置aop操作-->
<aop:config>
<!--2.1 配置切入点(被增强的方法)
id:给切入点起的名字
expre:通过表达式指定对哪个方法进行增强
-->
<aop:pointcut id="pointcut1" expression="execution(* cn.itcast.aop.Book.*(..)"></aop:pointcut>
<!--2.2 配置切面(增强用在具体方法)
ref:要增强上去的方法所在的bean
-->
<aop:aspect ref="myBook">
<!--配置增强类型
method:哪个方法作为前置增强
pointcut-ref:用到哪个方法上
-->
<aop:before method="before1" pointcut-ref="pointcut1"></aop:before>
</aop:aspect>
</aop:config>
</beans>
测试
public void test() {
ApplicationContext context =
new ClassPathXmlApplicationContext("bean3.xml");
Book book = (Book) context.getBean("book");
book.add();
}
//输出:
前置增强...
add....
环绕增强
Log4j 介绍
通过log4j,可以看到程序运行过程中更详细的信息
(1)需要导入log4j.jar 包
(2)复制这个文件到src下
### \u8F93\u51FA\u4FE1\u606F\u5230\u63A7\u5236\u62AC ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} %m%n
### \u8F93\u51FADEBUG \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/log.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ./logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = INFO
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ method:%l ] %m%n
### \u8F93\u51FAERROR \u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\u5230=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = ./logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ method:%l ] %m%n
###
log4j.rootLogger=debug, stdout
Spring整合项目
问题所在:
action调用service、service调用dao。每次访问action的时候,都要创建一次对象,且加载一次配置文件。
底层解决方案
在服务器启动的时候,创建对象加载文件
在底层使用监听器、servletContext对象
spring的解决方案
Spring封装了一个监听器(实现了servletContextListener接口)
第一步:导入jar包 spring-web-4.2.4RELEASE.jar
第二步: 在web.xml引入配置监听器
第三步:指定加载的spring配置文件的位置
在web.xml中添加
<!-- 指定spring配置文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:bean1.xml</param-value>
</context-param>
day03
今天内容
1、基于aspectj的注解aop操作(会用)
2、spring的jdbcTemplate操作(实现事务crud操作)
3、spring配置连接池
(1)配置c3p0连接池
(2)service和dao注入操作
4、spring事务管理
(1)事务的概念
(2)spring进行事务的api
(3)spring进行事务配置
一、基于aspectj的注解aop
第一步:在spring中创建对象bean
第二步: 在spring核心配置文件中,开启aop操作扫描
<!--开启aop扫描-->
<aop:aspectj-autoproxy/>
<!--生成对象-->
<bean id="book" class="cn.itcast.aop.Book"></bean>
<bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
第三步 在增强类上用注解来实现aop操作
@Aspect
public class MyBook {
@Before(value = "execution(* cn.itcast.aop.Book.*(..))")
public void before1() {
System.out.println("前置增强...");
}
}
二、spring的jdbcTemplate操作(仍然是记轮子,知道有这个东西存在就好)
spring对dao层的技术支持
2.1 使用jdbcTemplate对jdbc进行封装(需要自己创建表)
第一步:导入jar包,注意导入jdbc驱动的jar包
第二步:创建对象,设置数据库信息
第三步:创建jdbcTemole对象,设置数据源
第四步:调用jdbcTemple对象进行crud操作
总结:需要用的时候再查资料。知道有这么个东西在就行
三、spring配置连接池和dao使用jdbcTemplate
什么是连接池?
一般我们在项目中操作数据库时,都是每次需要操作数据库就建立一个连接,操作完成后释放连接。因为jdbc没有保持连接的能力,一旦超过一定时间没有使用(大约几百毫秒),连接就会被自动释放掉。而每次新建连接都需要140毫秒左右的时间,所以耗费时间比较多。若使用C3P0连接池来池化连接,随时取用,则平均每次取用只需要10-20毫秒。这在高并发随机访问数据库的时候对效率的提升有很大帮助。
使用步骤
第一步:导入jar包
第二步:在配置文件中,建立链接
原理:
配置中这么写:
在dao中调用jdbcTemplate
这里其实是对属性注入的复习(不断地注入注入。。。。)。
1、创建jdbcTemplate对象,class是他所在的包。而且他存在构造方法,这个时候就要进去看,他内部是用哪个数据成员来接收,然后传 < property >进去。
以上:jdbcTemplate的具体实现和连接池的具体配置没有实际操作,只是看了视频。
四、spring的事务操作
在hibernate中,手动的开启事务,执行事务,回滚事务、关闭事务。spring封装了这部分操作(用配置来实现)
两种事务管理的api
第一种:编程式事务管理(不用)
第二种:声明式事务管理
- 基于xml配置文件实现
- 基于注解实现
事务管理的接口:PlatformTransactionManager
针对不同的dao层框架,spring提供了不同的实现
4.2 搭建转账操作环境
前提准备
对现有的表进行操作
创建service 和 dao ,完成注入操作
知识回顾:
- service层又叫业务逻辑层, 比如说小王多1000,小马少1000.
- 而dao层不涉及业务逻辑,仅仅封装对数据库的操作(crud)
第一步:创建dao、service,在xml中完成注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
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">
<!-- 配置c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 注入属性值 -->
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///spring_day03"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--dao注入jdbcTemplate对象-->
<bean class="tx.itcast.dao.OrdersDao" id="ordersDao">
<property name="jdbcTemplate" ref="jdbcTemplate">
</property>
</bean>
<!--service中注入dao-->
<bean class="tx.itcast.service.OrdersService" id="ordersService">
<property name="ordersDao" ref="ordersDao"></property>
</bean>
<!--jdbc模板对象-->
<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
<!--源代码中有datesource的对象,所以要注入连接池提供的dataSourse-->
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
第二步:逻辑编写
小王账户的钱-1000
小马账户的钱+1000
Dao
// 少钱的方法
public void lessMoney() {
System.out.println("少钱执行");
String sql = "update account set salary=salary-? where username=?";
jdbcTemplate.update(sql, 1000, "xiaowang");
}
// 多钱的方法
public void addMoney() {
System.out.println("多钱执行");
String sql = "update account set salary=salary+? where username=?";
jdbcTemplate.update(sql, 1000, "xiaoma");
}
Service
// 调用dao
//业务逻辑,写转账业务
public void accountMoney() {
ordersDao.addMoney();
// 这里可能出现的异常,那么数据库只加,不减。
int i = 8/0;
ordersDao.lessMoney();
}
第三步:针对事务能出现的异常,我们进行事务管理
用配置文件的方式,添加事务管理
分三步,具体看代码
<!--事务管理部分-->
<!--第一步:配置事务管理器-->
<bean id="DataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--对事务管理器的属性进行注入
dataSource
-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--第二步: 配置事务增强
规定一个名称
指定针对的事务管理器:DataSourceTransactionManager
-->
<tx:advice id="txadvice" transaction-manager="DataSourceTransactionManager">
<!--做事务操作-->
<tx:attributes>
<!--设置进行事务操作的方法,匹配规则
目的是规定对哪些方法进行增强
propagation:隔离级别
-->
<tx:method name="account*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--第三步:配置切面-->
<aop:config>
<!--切入点-->
<aop:pointcut id="pointcut1" expression="execution(* tx.itcast.service.OrdersService.*(..))"
<!--切面-->
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
</aop:config>
验收
仍是之前的代码,由于对 Service的事务逻辑进行了事务管理的增强,现在事务逻辑过程中,
用注解的方式完成事务管理
<!--第一步:配置事务管理器-->
<bean id="DataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--对事务管理器的属性进行注入
dataSource
-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--第二步:开启事务注解-->
<tx:annotation-driven transaction-manager="DataSourceTransactionManager"/>
第三步:在要增强事务管理功能的类上面加上注解