JAVAEE 开发分成三层结构:
- WEB 层:Spring MVC.
- 业务层:Bean 管理:(IOC)
- 持久层:Spring 的 JDBC 模板.ORM
Spring
spring核心有两部分:
(1)控制反转 ioc:
- 比如现在有普通类,在这个类里面有普通的方法,调用这个类里面的普通的方法,需要创建类对象,使用对象调用方法。
- 创建类的对象,使用原始方式new对象。使用ioc实现对象创建,不需要手动new对象,通过配置文件方式创建对象
** 把对象创建交给spring配置
(2)面向切面 aop:
- 不通过修改源代码方式增强类里面的方法
- aop底层动态代理
一. ioc入门
1.导入spring相关jar包
2.创建类,创建普通的方法
3.创建spring配置文件,配置user对象创建
(1)创建spring配置文件,名称和位置不是固定的
建议放到src下面
名称没有固定要求,官方建议:applicationContext.xml
(2)在spring配置文件引入schema约束
(3)在spring配置文件配置对象
<bean id="user" class="cn.itcast.ioctest.User"></bean>
4.测试如何获取配置出来的user对象
根据实例理解原理:创建类以及类中普通的方法---->配置xml文件(配置文件,配置对象)----->获取对象
二.Spring的bean管理
1 什么是bean管理
两个操作:
(1)创建对象(bean实例化)
(2)设置类里面属性值(注入属性)
2 spring的bean管理有两种方式
(1)基于xml配置文件方式
(2)基于注解方式
3.Bean实例化的方式
3.1 在spring里面通过配置文件创建对象
(1)创建对象操作
3.2 bean实例化(创建对象)三种方式实现
第一种 使用类的无参数构造创建(重点)
第二种 使用静态工厂创建(了解)
(1)创建静态的方法,返回类对象
第三种 使用实例工厂创建(了解)
(1)创建不是静态的方法,返回类对象
4.bean标签常用属性
id属性
(1)根据id属性值获取对象
(2)在一个spring配置文件中,可以有多个bean标签,但是bean标签id属性值不同
class属性
(1)类的全路径
name属性
(1)name属性作用和id属性一样的
(2)id属性值里面不能包含特殊符号的
(3)name属性值可以包含特殊符号 /user
scope属性
(1)主要作用:配置创建对象是单实例还是多实例对象
(2)属性值:
- 默认值,singleton,表示单实例对象
- prototype,表示多实例对象
** action是多实例对象
request:把创建对象放到request里面
session:把创建对象放到session里面
globalSession:把创建对象放到globalSession里面
- Bean工厂
(1)ApplicationContext和BeanFactory区别
- ApplicationContext加载配置文件时候,把配置文件对象创建
- BeanFactory加载配置文件时候不会创建对象,在获取对象时候创建
** spring配置文件在服务器启动时候加载最合适,创建对象
底层原理:
- ServletContext对象:当服务器启动时候,每个项目有一个ServletContext对象,是整个web项目范围的域对象
- 监听器:监听ServletContext对象创建和销毁
(2)在开发中,一般让配置文件在服务器启动时候加载,把配置文件中对象创建
6.Bean生命周期配置(了解)
创建servlet时候,执行init方法
销毁servlet时候,执行destory方法
7.属性注入介绍
(1)在类里面有属性,向类里面属性中设置值,这个过程称为属性注入
(2)
7.1使用有参数构造注入
创建类,定义属性,生成有参数构造
/**
- 有参数构造注入
- @author asus
*/
public class Book {
private String bname;
private String author;
(1)//生成有参数构造
public Book(String bname, String author) {
this.bname = bname;
this.author = author;
}
public void add() {
System.out.println("book:"+bname+"::"+author);
}
}
(2) 配置属性注入
7.2使用set方法注入(重点)
创建类,定义属性,生成属性set方法
/**
- set方法注入
- @author asus
*/
(1)public class Orders {
private String oname;
private String oaddress;
//生成set方法
public void setOname(String oname) {
this.oname = oname;
}
public void setOaddress(String oaddress) {
this.oaddress = oaddress;
}
public void add() {
System.out.println("orders:"+oname+"::"+oaddress);
}
}
(2)配置属性注入
7.3
注入对象类型属性(重点)
第一步 在service定义dao类型属性
public class UserService {
//目的:在service获取dao对象
//把dao对象注入到service
//1 定义UserDao类型属性
private UserDao userDao;
//2 生成set方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
第二步 实现配置
<!-- 注入对象类型属性 -->
<bean id="userDaoImpl" class="cn.itcast.attr.UserDao"></bean>
<bean id="userService" class="cn.itcast.attr.UserService">
8.spring分模块配置开发
9.注入复杂类型属性(会用)
1 数组
2 List集合
3 Map集合
4 Properties
/**
- 复杂类型属性
- @author asus
*/
public class Customer {
//定义属性
private String[] arrs;
private List<String> list;
private Map<String,String> map;
private Properties properties;
//set方法
public void setArrs(String[] arrs) {
this.arrs = arrs;
}
public void setList(List<String> list) {
this.list = list;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public void find() {
System.out.println("arrs: "+Arrays.toString(arrs));
System.out.println("list: "+list);
System.out.println("map: "+map);
System.out.println("properties: "+properties);
}
}
<bean id="customer" class="cn.itcast.attr.Customer">
<!-- 数组 -->
<property name="arrs">
<list>
<value>lucy</value>
<value>mary</value>
<value>jack</value>
</list>
</property>
<!-- list -->
<property name="list">
<list>
<value>小王</value>
<value>小金</value>
<value>小奥</value>
</list>
</property>
<!-- map-->
<property name="map">
<map>
<entry key="football" value="足球"></entry>
<entry key="basketball" value="篮球"></entry>
</map>
</property>
<!-- properties -->
<property name="properties">
<props>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
<prop key="jdbcUrl">jdbc:mysql:///day01</prop>
</props>
</property>
</bean>
10.IOC和DI区别
ioc:控制反转,把对象创建不是new出来的,通过spring配置出来的
(1)spring创建对象
di:依赖注入
(1)属性注入,向类里面属性中设置值
ioc和di关系:
(1)di需要在ioc基础之上完成
(2)向类里面设置属性值,首先创建类的对象,使用对象才可以设置
- Spring的bean管理(注解)
11.1 注解介绍
什么是bean管理
(1)创建对象
(2)注入属性
使用注解方式实现创建对象和注入属性
什么是注解?
(1)注解代码中特殊标记
(2)写法: @注解名称(属性名称1=属性值1, 属性名称2=属性值2)
(3)注解可以使用类上面、使用方法上面、使用在属性上面
(4)为什么使用注解:替代配置文件实现一部分功能,简化配置
12.Spring注解开发准备
12.1 导入jar包
(1)导入基本的jar包
(2)导入aop的jar包
12.2 创建类,创建方法
public class User {
public void add() {
System.out.println(“add…”);
}
}
12.3 创建spring配置文件,引入约束
(1)做spring的ioc注解开发,引入新的约束
12.4开启注解扫描
13.注解创建对象
spring创建对象注解
(1)在创建对象所在类上面使用注解实现
(2)注解创建对象是单实例还是多实例
scope注解不写,默认是单实例对象
(3) spring创建对象注解总结:
1)在spring里面创建对象可以使用注解 有四个
2)这四个注解功能都是一样的,都可以创建对象
14.注解注入属性
注入普通类型属性
(1)在要注入值的属性上面使用注解 @Value
(2)注入对象类型属性(重点)
首先把对象使用注解创建
第一个注解: @Autowired
//使用注解方式注入userDao对象
//使用第一个注解 @Autowired 自动装配
@Autowired
private UserDao userDao;
//注解方式不需要生成set方法
AOP
aop:Aspect Oriented Programming面向切面(方面)编程,不通过修改源代码方式实现
1.Aop操作准备
(1)创建spring核心配置文件,导入aop的约束
(2)使用表达式配置切入点
1)execution(* cn.itcast.UserDao.update(…))
- 增强UserDao类里面update方法
2)execution(* cn.itcast.UserDao.*(…))
- 增强UserDao类里面所有方法
3)execution(* .(…))
- 所有增强
4)execution(* save*(…))
- 对方法名称,如果方法名是以save开头的进行增强
5)execution(* cn.itcast.dao…*(…))
- 两个点表示当前包和子包,孙包,类方法进行增强
6)execution(* cn.itcast.dao.GenericDAO+.*(…))
-
- ;针对接口情况,接口里面所有实现类
(3)通知类型
通知类型
前置通知:在方法之前执行
后置通知:在方法之后执行
环绕通知:在方法之前和之后执行
异常通知:被增强的方法运行过程中,出现异常,执行这个通知
最终通知:类似于finally,总会被执行
- ;针对接口情况,接口里面所有实现类
(4)实例运用
1)创建被增强类,创建被增强的方法
public class User {
public void add() {
System.out.println(“user add…”);
}
}
public class MyUser {
//前置通知
public void before1() {
System.out.println(“before…”);
}
//后置通知
public void after1() {
System.out.println("after..............");
}
//环绕通知
public void around1() {
System.out.println("环绕..........");
}
//异常通知
public void throw1() {
System.out.println("异常.................");
}
//最终通知
public void finally1() {
System.out.println("最终..................");
}
}
2)创建User和MyUser类对象
<bean id="user" class="cn.itcast.aop.User"></bean>
<bean id="myUser" class="cn.itcast.aop.MyUser"></bean>
3)配置切入点和切面
(1)配置切入点
(2)配置切面
<!-- 创建对象 -->
<bean id="user" class="cn.itcast.aop.User"></bean>
<bean id="myUser" class="cn.itcast.aop.MyUser"></bean>
<!-- aop配置 -->
<aop:config>
<!-- 配置切入点
expression:使用表达式配置切入点
execution(* cn.itcast.aop.User.*(..))
-->
<aop:pointcut expression="execution(* cn.itcast.aop.User.*(..))" id="p1"/>
<!-- 配置切面 -->
<aop:aspect ref="myUser">
<!-- 配置前置通知 作为前置通知的增强的方法名称-->
<aop:before method="before1" pointcut-ref="p1"/>
</aop:aspect>
</aop:config>
Aop后置通知
Aop环绕通知
Aop异常通知
Aop最终通知
2.基于aspectj注解aop
(1)使用注解方式实现aop操作
第一步 创建对象
第二步 在spring核心配置文件中,开启aop操作
1)引入约束
2)开启aop自动代理
3) 在增强类上面使用注解完成aop操作
在增强类上面使用@Aspect注解
在增强方法上面配置不同类型通知
/*
-
增强类
*/
@Aspect
public class MyUser {//让这个方法在add方法之前执行,前置通知
@Before(value=“execution(* cn.itcast.aop.User.add(…))”)
public void before1() {
System.out.println(“前置通知…”);
}//后置通知
@AfterReturning(value=“execution(* cn.itcast.aop.User.update(…))”)
public void after1() {
System.out.println(“后置通知…”);
}//环绕通知
//之前和之后都执行
@Around(value=“execution(* cn.itcast.aop.User.delete(…))”)
public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("环绕通知之前................"); //这个方法里面获取被增强的方法,让执行 proceedingJoinPoint.proceed(); System.out.println("环绕通知之后................");
}
//异常通知
@AfterThrowing(value=“execution(* cn.itcast.aop.User.find(…))”)
public void throw1() {
System.out.println(“异常通知…”);
}//最终通知
@After(value=“execution(* cn.itcast.aop.User.find(…))”)
public void finally1() {
System.out.println(“最终通知…”);
}
}
4)配置切入点注解
在增强类里面创建方法,使用注解配置切入点
在增强的方法中使用切入点
JDBC
1.Spring配置连接池(重点)
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- set方法住人 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql:///spring_day03"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
2.spring配置c3p0连接池
3.在配置文件进行配置
4.引入外部属性文件
(1)在src下面创建 jdbc属性文件,文件类型properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring_day03
jdbc.user=root
jdbc.password=123
(2)在spring配置文件中使用资源文件中数据库信息
第二种方式使用:
<context:property-placeholder location="classpath:jdbc.properties"/>
(3)配置连接池部分具体使用
day03
Spring的事务管理
1.Spring事务管理api
(2)使用spring做事务管理,首先创建接口实现类对象(创建事务管理器)
2.实例(搭载转账环境)
1)创建数据库表,添加测试数据
2)在配置文件引入完全约束(到资料找到)
(3)完成service、dao和jdbcTemplate注入关系
<bean id="userService" class="cn.itcast.pool.UserService">
<!-- 注入userDao对象 -->
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="cn.itcast.pool.UserDao">
<!-- 注入jdbcTemplate -->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!-- 创建JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 注入DataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
(4)public class UserDao {
//dao注入jdbcTemplate对象
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//少钱的方法 mary -1000
public void lessMoney() {
String sql = "update account set money=money-? where username=?";
jdbcTemplate.update(sql,1000,"mary");
}
//多钱的方法 jack+1000
public void moreMoney() {
String sql = "update account set money=money+? where username=?";
jdbcTemplate.update(sql, 1000,"jack");
}
}
如果lucy少了1000之后,出现异常,mary不会多1000.丢失了,添加事务解决
3.声明式事务(xml)(重点)
第一步 配置事务管理器
事务管理器中注入dataSource
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入DataSource -->
<property name="dataSource" ref="dataSource"></property>
</bean>
第二步 配置增强/通知
第三步 配置切面