Spring框架
第一 耦合
耦合:程序代码之间的依赖关系
紧密的依赖关系:强耦合
松散的依赖关系:松散耦合
解耦:
1.面向接口编程 (x)
2.配置文件 (x)
3.反射解耦
class.forName("全限定类名");
spring的结构功能图
第二 IOC的概述
IOC:传统获取对象的方式:new出来
ioc的方式是从容器中获取(map集合)
* 使用ioc:主要目的就是为了解耦
* ioc的底层实现原理:反射
Inversion Of Control:IOC
控制反转
(变主动为被动思想,ioc就相当于一个房屋中间,你之前new 对象就相当于自己去找房子,有了ioc(房屋中间),你只要把相关信息注册进去就会得到房源信息,降低了你和房子之间的耦合)。
第三 Spring IOC的入门
搭建环境
1.导入jar包
2.编写配置文件(xml格式)
从spring容器中获取对象
1.java代码
1.获取spring容器
ClassPathXmlApplicationContext
String : 从类路径下查找一个xml配置文件
2.从容器中获取对象
getBean方法
String类型的参数:被Spring容器管理的对象的唯一标识(beanId)
2.配置对象交给spring容器管理
<bean id="bean的唯一标识" class=“实现类的全限定类名”/>
3.属性
** Scope 作用
singleton(单例:默认值) | prototype(多例)
init-method
destory-method
单实例:
<!-- 创建对象,交给spring容器(map<String,Object>)管理 -->
<!--
bean:创建对象,存入spring容器
id:bean对象的唯一标识(全局唯一)
class:实现类的全限定类名
scope : 配置spring创建对象的作用域(生命周期)
singleton:单例,容器创建的时候创建对象,容器关闭的时候销毁对象(默认值)
prototype:(多例),当调用方法的时候创建对象,调用结束,垃圾回收
request:创建一个对象,存入request域中
session:创建一个对象,存入session域中
-->
<!-- init-method : 初始化方法
在创建对象之后。立即执行的对象中的方法
* Thread thread = new Thread();
* thread.start();
destroy-method :销毁方法
在spring容器销毁的时候,对象销毁,立即执行的对象中的方法
-->
<bean id="customerService" scope="singleton" init-method="init" destroy-method="destory"
class="cn.itcast.service.impl.CustomerServiceImpl"></bean>
spring中的IOC注解
使用spring注解的注意事项:
1.开启对注解们的支持
2.导入相关的支持jar包
Ioc的注解,
依赖jar包:spring-aop
在xml中开启对ioc注解的支持
1.创建对象的注解
@Component
@Controller
@Service
@Repository
* 默认情况下:创建对象交给spring容器管理的唯一标识:当前类名(首字母小写)
* value :配置bean的唯一标识
2.生命周期的注解
@Scope : 创建对象的作用域
singleton :单例(默认值)
prototype :多例
@PostConstruct
初始化方法(配置到方法上:对象创建之后立即执行的方法)
@PreDestory
销毁方法(容器关闭,执行的方法)
3.依赖注入的注解
@AutoWired:
按照类型注入
按照属性名称作为beanid从容器查找
@Qualifier:配置到属性上和@AutoWwired配合使用
value:bean的唯一标识
按照指定的beanId从容器查找
@Resource
name:bean的唯一标识
按照指定的beanId从容器中查找
@Value
注入被spring管理的properties文件中的内容
1.将配置文件交给spring容器管理(加载)
<bean id="propertySource" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"></property>
</bean>
2.使用@Value结合sp-el表达式获取数据(${})
@Value("${key}")
4.纯注解编程
* 替换xml文件
@Configuration:声明配置类
@ComponentScan :指定扫描的包
basePackages:接受一个string类型的数组
@PropertySource:指定加载的properties配置文件
@Import:导入其他的配置类
value:接受一个字节码的数组
(其他的配置类的字节码)
@Bean(****)
配置到方法上,表明此方法的返回值交给spring容器管理
name:bean的唯一标识
第四 依赖注入
di(dependency injection):依赖注入
根据配置,自动对依赖对象或者基本数据类型的属性进行赋值
依赖注入有两种方式
i.构造方法
ii.set方法
注入基本数据类型
1.构造方法
* 需要提供一个对应参数的构造方法
* xml配置文件中
<constructor-arg> 构造方法的方式注入
name: 使用属性名定位
index: 使用属性的索引定位
type: 使用属性数据类型定位
------------
value:注入基本数据类型
ref: 注入被spring管理的bean对象
2.set方法注入
* 需要提供属性的set方法
* xml配置文件
<property> set方法的方式注入
name:set方法后面的部分(首字母小写)
value:注入基本数据类型
ref:注入被spring管理的bean对象
注入被spring管理的javaBean对象
* 被注入的javaBean对象,必须要被spring容器管理
第五 spring中的单元测试
* 导入spring对单元测试的jar包(spring-test.junit)
* 使用单元测试
i.指定spring的单元测试环境
@RunWithd(SpringJunit4ClassRunner.class)
ii.指定spring容器的配置信息
@ContextConfiguration
locations:配置文件的路径
classses:配置类的字节码文件
* 直接使用注解的形式,注入对象
第六 动态代理
* 在不改变程序源码的前提下:对方法进行增强
基于接口的动态代理:jdk提供的Proxy
* 创建出的动态代理对象,实现了此接口
基于子类的动态代理:cglib
* 创建出的动态代理对象:是被代理对象的一个子类
Customer load 方式查询的对象 $$customer_##
final
* 被代理对象不能使用final修饰
* 案例 (在调用service中任意的方法的时候,打印日志)
1.进入方法之前打印日志
2.调用方法得到返回值之后打印日志
3.抛出异常打印日志
4.执行最终代码块打印日志
第七 spring中的AOP
AOP:Aspect Oriented Programming
面向切面编程
OOP:Object Oriented Programming
面向对象编程
aop:在不改变程序源代码的前提下:对方法进行增强
* 学习AOP重点关注点:
关注的是额外的功能模块
* aop的底层原理
动态代理
使用AOP的好处
1.减少开发量
2.维护简单
* aop的专业术语
Joinpoint(连接点)
被代理对象中的所有方法
Pointcut(切入点):
被代理对象中所有被增强的方法
Advice(通知/增强):
增强部分的代码块
前置通知:进入方法之前执行的代码块
后置通知:进入方法之后得到返回值执行的代码块
异常通知:抛出异常的时候执行的代码块
最终通知:finally中执行的代码块
环绕通知
Aspect(切面):是切入点和通知(引介)的结合
* 定义那个方法需要被怎样增强
springAop的入门
* 功能模块 和 配置
* 搭建一个aop的运行环境
1.导入jar包(ioc 和 aop)
配置spring的AOP
* 将切面类交给spring容器管理
1.xml的配置方式
1.将切面类交给spring容器管理
2.使用aop:config声明配置AOP
3.配置一个切入点
4.使用aop:aspect配置切面
*
<aop:config>
<aop:pointcut expression="execution(修饰符 返回值 包名..类名.方法名(参数))" id="切入点的唯一标识" />
<aop:aspect ref="切面类的引用">
<!--定义通知类型
method:切面方法
pointcut-ref:切入点的引用
-->
<aop:before /> //前置通知
<aop:after-returning /> //后置通知
<aop:after-throwing /> //异常通知
<aop:after /> //最终通知
<aop:around/> //环绕通知
</aop:aspect>
</aop:config>
2.注解结合xml的配置方式
* 开启对注解的支持
* 开启对aop注解的支持
<aop:aspectJautoproxy/>
1.将切面类交给spring容器管理
2.在切面类上配置aop(所有的xml的aop配置)
1.声明切面类
@Aspect
2.定义切入点
@Pointcut
value:切入点表达式
* 配置到方法上:是一个空的方法
* 引用此切入点表达式:方法名()
3.定义通知类型
@Before
@AterReturning
@AfterThrowing
@After
@Around
* value:切入点表达式或者切入点表达式的引用(方法名())
3.纯注解的配置方法
@EnableAspectJAutoProxy (开启对aop注解的支持)
第八 JdbcTemplate操作
JdbcTemplate是spring提供的一个对jdbc操作的薄薄封装的一个框架
*
spring-jdbc : jdbc操作的jar包
spring-tx :spring对事务的支持包
在xml的配置中,使用jdbctemplate有两种方式
1.在dao中定义一个jdbctemplate对象,并注入
2.在创建dao的时候继承jdbcDaoSupport的父类,注入一个数据库连接池
在注解的配置中,使用jdbcTemplate只有一种方式
1.在dao中定义一个jdbctemplate对象,并注入
第九 spring中的事务管理
spring的事务管理:是通过spring的AOP实现的
* 事务管理器(切面类)
PlatformTransactionManager : 接口
事务管理器的实现类
DataSourceTransactionManager:仅对dbc操作数据库有效
HibernateTransactionManager :对hibernate操作有效
JpaTransactionManager :对jpa操作有效
* 事务的传播行为
方法间的嵌套调用的时候,对事务的支持情况
REQUIRED | SUPPORTS
* 超时时间
默认值:-1(不超时)
* 是否是只读事务
false(增删改)|true(查询)
* 增删改
事务的传播行为:REQUIRED
是否只读:false
* 查询
事务的传播行为:SUPPORTS
是否只读:true
spring的事务管理:spring-tx
* 不关注java代码的编写
* 配置事务
1:将事务管理器交给spring容器管理
xml的事务配置
2:配置spring的事务通知
<tx:advice id="事务通知的唯一标识" transaction-manager="事务管理器的引用">
<tx:attributes>
<tx:method name="方法名(可以使用通配符)" propagation="事务传播行为" read-only=“是否制度”/>
</tx:attributes>
</tx:advice>
3:配置spring的事务管理的AOP
<aop:config>
<aop:pointcut expression="切入点表达式" id=“切入点表达式的唯一标识”/>
<aop:advisor advice-ref="事务通知的引用" pointcut-ref="切入点表达式的引用" />
</aop:config>
注解集合xml的事务配置(*****)
1.开启对事务注解的支持
<tx:annotation-driven/>
2.将事务管理器交给spring容器管理
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
3.在需要事务的类或者方法上使用@Transactional注解配置事务
纯注解的事务配置
@EnableTransactionManagement:开启对事务注解的支持
出身决定命运,但努力一定不会错。