业务层框架Spring学习小结
IOC:作用(控制反转)
什么是ioc
控制反转是把创建对象的权利交给框架,是框架的重要特征,它包含依赖注入,依赖查找。
作用:
主要作用减小计算机程序间的耦合性(减小代码间的依赖关系)
实现ioc解决程序的耦合性
一、准备spring的开发包
二、创建业务层的接口和实现类
三、准备xml配置文件
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
2.再配置文件创建<bwan> 标签来配置service和dao
*bean 标签:用来配置让spring创建对象 ,并且存入ioc容器中
id属性:对象的唯一标识符
class:创建对象的全限定类名(com.itheima.dao.daoImpl.接口实现类名),默认情况下调用无参构造函数,**如果方法没有无参构造则创建失败**
scope:指定对象的作用范围。
*singleton :默认值,单例的.
*prototype :多例的.
*request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
*session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
*global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么
globalSession 相当于 session.
init-method:指定类中的初始化方法名称。
destroy-method:指定类中销毁方法名称。+
生命周期问题:
单例对象:scope="singleton"
一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了。
对象活着:只要容器在,对象一直活着。
对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
多例对象:scope="prototype"
每次访问对象时,都会重新创建对象实例。
生命周期:
对象出生:当使用对象时,创建新的对象实例。
对象活着:只要对象在使用中,就一直活着。
对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。
四、测试实习对象是否创建成功
在main方法中用
1. ApplicationContext 接口,就是在获取 spring 容器
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
**实现获取spring容器的方法:
1. BeanFactory :Spring容器的顶层接口
BeanFactory在使用方法时创建对象
2. ApplicationContext :是BeanFactory的子接口
ApplicationContext在读取配置文件的时候创建对象
二者的区别主要是创建对象的时间,ApplicationContext方法更多
ApplicationContext的主要实现类:
**ClassPathXmlApplicationContext :
它是从类的根路径下加载配置文件 推荐使用这种
FileSystemXmlApplicationContext :
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
**AnnotationConfigApplicationContext:
当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
2. 根据 bean 的 id 获取对象
IAccountService aService = ac.getBean("accountService",IAccountService.class);
IAccountService aService = (IAccountService) ac.getBean("accountService");
3. 通过实例化出来的类调用用方法:
aService。findAll();
Spring的依赖注入问题
一、什么是依赖注入:
就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置
的方式,让 spring 框架来为我们注入。
二、依赖注入的方法和方式
1. 使用构造函数的方式,给 service 中的属性传值
要求:方法需要提供有参构造
涉及的标签:
<constructor-arg></constructor-arg>
属性:
index :指定参数在构造函数参数列表的索引位置
name :指向参数的名称在构造函数中
type :指定参数在构造函数中的数据类型
===========以上解决了给谁赋值的问题==============
value :赋值基本数据类型
ref :将bean中以定义的的函数赋值给参数(所以配置文件中必须有bean)
===========以上是给它赋什么值的问题==============
2. 使用set的方式给service函数赋值
要求:方法需要提供set方法
涉及的标签:
<property></property>
属性:
name:找的是类中 set 方法后面的部分(是用set后面的方法名)
============以上是赋值给谁================
ref:给属性赋值是其他 bean 类型的
value:给属性赋值是基本数据类型和 string 类型的
3. List,Set,properties,Map等的赋值
就是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。
我们这里介绍注入数组,List,Set,Map,Properties
涉及的标签:
<property></property>
属性:
在注入集合数据时,只要结构相同,标签可以互换
**给数组注入数据 **
<property name="myStrs">
<set>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</set>
</property>
<!-- 注入 list 集合数据 -->
<property name="myList">
<array>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</array>
</property>
<!-- 注入 set 集合数据 -->
<property name="mySet">
<list>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</list>
</property>
===============================注入 Map 数据================================
<property name="myMap">
<props>
<prop key="testA">aaa</prop>
<prop key="testB">bbb</prop> prop标签中没有value属性所以要在标签体中赋值
</props>
</property>
<!-- 注入 properties 数据 -->
<property name="myProps">
<map>
<entry key="testA" value="aaa"></entry>
<entry key="testB">
<value>bbb</value>
</entry>
</map>
</property>
#Spring 注释的使用
前提:
在基于注解的配置中,我们还要多拷贝一个 aop 的 jar 包
基于注解整合时,导入约束时需要多导入一个 context 名称空间下的约束。
由于我们使用了注解配置,此时不能在继承 JdbcDaoSupport,需要自己配置一个 JdbcTemplate
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
在配置文件中:
告知 spring 创建容器时要扫描的包
<context:component-scan base-package="com.itheima"></context:component-scan>
#常用注解
#用于创建对象的
1. @Component
作用:
把资源让 spring 来管理。相当于在 xml 中配置一个 bean。
属性:
value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写
1.1 @Controller @Service @Repository
@Controller :一般用于表现层的注解。
@Service :一般用于业务层的注解。
@Repository :一般用于持久层的注解。
果注解中有且只有一个属性 要赋值时是 ,且名称是 value ,value 在赋值是可以不写
#用于注入数据的
1. @Autowired
作用:
自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他 bean 类型。当有多个类型匹配时,使用要注入的对象变量名称作为 bean 的 id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。
2. @Qualifier
作用:
在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和@Autowire 一起使用;但是给方法参数注入时,可以独立使用。
属性:
value:指定 bean 的 id。
3. @Resource
作用:
直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。
属性:
name:指定 bean 的 id。
4. @Value
作用:
注入基本数据类型和 String 类型数据的
属性:
value:用于指定值
##用于改变作用范围的
@Scope
作用:
指定 bean 的作用范围(设置单列双列)。
属性:
value:指定范围的值。
取值:singleton prototype request session globalsession
##新注解说明
1. @Configuration
作用:
用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用 AnnotationApplicationContext(有@Configuration 注解的类.class)。
属性:
value:用于指定配置类的字节码
2. @ComponentScan
作用:
用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:<context:component-scan base-package="com.itheima"/>是一样的。
属性:
basePackages:用于指定要扫描的包。和该注解中的 value 属性作用一样。
3. @Bean
作用:
该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。
属性:
name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。
4. @PropertySource
作用:
用于加载.properties 文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。
属性:
value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:
##AOP
什么是AOP:
AOP:它是一种思想,就是面向切面编程,就是他关心的是同一层面上的一些共性/大量重复操作抽取,就是通过预编译和运行时动态代理来实现程序功能统一维护的一种技术;
AOP : 底层运用动态代理的形式来实现
作用: 在程序运行期间,不修改源码对已有方法进行增强。
优势: 减少重复代码
提高开发效率
维护方便
动态代理:
特点:
字节码文件随用随创建,随时加载。
动态代理的两种实现方式:
1. 基于接口的动态代理,由JDK提供**要求被代理的类必须实现一个接口
用 Proxy类 来实现
Proxy.newProxyInstance(三个参数)
参数含义:
ClassLoader:和被代理对象使用相同的类加载器。
Interfaces:和被代理对象具有相同的行为。实现相同的接口。
InvocationHandler:如何代理。
策略模式:使用场景是:
数据有了,目的明确。
如何达成目标,就是策略。
`IActor proxyActor = (IActor) Proxy.newProxyInstance(
actor.getClass().getClassLoader(),
actor.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
})`
Throwable
Java中有个java.lang.Throwable类,这个类是Java中所有异常和错误的基类。Throwable下有两个大类那就是异常(Exception)和错误(Error)。
2. 基于子类的动态代理,由第三方的CGLib提供,如果报asmxxx异常需要导入jar包
使用它的类不能被final修饰(最终类)
AOP 相关术语
1. Joinpoint( 连接点):
所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的连接点。
2. Pointcut( 切入点):
所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
3. Advice( 通知/ 增强):
所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。
通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
4. Introduction( 引介):
引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field。
5. Target( 目标对象):
代理的目标对象。
6. Weaving( 织入):
是指把增强应用到目标对象来创建新的代理对象的过程。spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。
7. Proxy (代理):
一个类被 AOP 织入增强后,就产生一个结果代理类。
8. Aspect( 切面):
是切入点和通知(引介)的结合。
#执行了流程
Spring在运行时是监视切入点方法执行,当切入点方法执行的时候动态调的建立目标对象的代理对象,根据通知类别,在代理对象的对应位置,将对应功能织入,完成代理逻辑的运行。
#利用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: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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
第二步:配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
注入dataSoure
<property name="dataSource" ref="dataSource"></property>
</bean>
第三步:配置事务属性
###指定方法名称:是业务核心方法
read-only:是否是只读事务。默认 false,不只读。
isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。
propagation:指定事务的传播行为。
timeout:指定超时时间。默认值为:-1。永不超时。
rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。
没有默认值,任何异常都回滚。
no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回
滚。没有默认值,任何异常都回滚。
<!--在 在 tx:advice 标签内部 配置事务的属性 -->
<tx:attributes>
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
</tx:attributes>
第四步:配置 AOP 切入点表达式
使用aop:aspect配置切面
aop:config:
作用:用于声明开始 aop 的配置
使用aop:pointcut配置切入点表答式
<aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))"
id="pt1"/>
使用aop:xxx方式配置对应通知类
第五步:配置切入点表达式和事务通知的对应关系
在 aop:config 标签内部:建立事务的通知和切入点表达式的关系
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>
#Spring 中注释方法进行事务的控制
第一步:导入约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
第二步:配置Spring创建容器时要扫描包
要有context约束
<context:component-scan base-package="com.itheima"></context:component-scan>
第三步 :配置事务管理器
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
第四步: 在业务层使用 @Transactional 注解添加事务级别
@Transactional
作用:配置事务的属性,就是业务级别
属性
read-only:是否是只读事务。默认 false,不只读。
isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。
propagation:指定事务的传播行为。
timeout:指定超时时间。默认值为:-1。永不超时。
rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。
没有默认值,任何异常都回滚。
no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回
滚。没有默认值,任何异常都回滚。
第五步:配置文件开启Spring对注释的支持
<tx:annotation-driven transaction-manager="transactionManager"/>
总结:Spring框架就是一管理对象的容器,降低代码简单耦合性,提高程序的效率,降低程序简单依赖;
重点掌握:
1.bean.xml 配置文件的配置 ,注解的使用,及两个结合使用。
2.重点掌握AOP,IOC 的使用和理解