文章目录
- 前言
- 基本概念
- 程序之间的耦合性
- 什么是Spring
- Spring体系结构
- Spring依赖Maven坐标
- Bean
- 什么是Bean
- 与javaBean的区别
- Bean的分类
- 普通Bean
- 普通工厂Bean
- 静态工厂Bean
- Bean作用范围
- Bean生命周期
- 单例对象的生命周期
- 多例对象的生命周期
- IOC
- IOC容器
- IOC容器接口
- BeanFactory接口
- ApplicationContext接口
- ClassPathXmlApplicationContext类
- FileSystemXmlApplicationContext类
- AnnotationConfigApplicationContext类
- 注册Bean
- 使用默认构造函数创建
- 使用某个工厂的方法注册bean
- 使用静态工厂中的静态方法注册bean
- 依赖注入
- 注入的数据类型
- 注入方式
- 使用构造函数注入
- 基于xml
- 优点
- 缺点
- 使用set方法注入
- 基于xml
- 复杂类型注入
- 优点
- 缺点
- 完全注解开发
- 用于替代xml的注解
- @Configuration
- @ComponentScan
- 属性
- value
- value/basePackages
- @Bean
- 属性
- name
- @Import
- 属性
- value
- @PropertySource
- 属性
- value
- 用于创建对象的注解
- @Component
- 属性
- value
- @Controller @Service @Repository
- 用于注入数据的
- 基本数据类型和String
- @Value
- 属性
- 其他bean类型
- @Autowired
- @Qualifier
- 属性
- @Resource
- 属性
- 集合类型
- 用于改变bean作用范围的
- @Scope
- 属性
- value
- 和bean的生命周期相关的
- @PostConstruct
- @PreDestroy
- Spring整合Junit
- AOP
- 什么是Aop
- AOP的相关术语
- 切入点表达式
- 语法
- 通配写法
- 配置AOP
- 开始
- 配置切面
- 配置切入点表达式
- 配置对应的通知类型
- 完全注解开发
- @EnableAspectJAutoProxy
- @Aspect
- @Before
- @AfterReturning
- @AfterThrowing
- @After
- @Around
- @Pointcut
- JDBCTemplate和Spring声明式事务管理
- 总结
前言
本文随着作者自身技术的增加随时会更新而不会做出任何提示。
学习之前应该掌握的单词:
Context | 环境 |
singleton | 单例 |
prototype | 原型 |
entry | 条目 |
基本概念
程序之间的耦合性
程序的耦合指的是程序之间的依赖关系包括类之间的依赖和方法之间的依赖,解耦是指降低程序之间的耦合性,因为完全消除耦合性是不可能的,在实际开发中,我们因该做到编译期不依赖,运行期才依赖。具体的步骤为:
- 在创建对象时使用反射创建对象而避免使用new关键字
前者依赖的是一个字符串而后者依赖的是一个具体的类,但是前者的以来字符串往往是写死的 - 通过读取配置文件来获取创建对象的依赖字符串
什么是Spring
Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 Ioc(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。
Spring体系结构
Spring依赖Maven坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jcl</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
Bean
什么是Bean
在 Spring 中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是一个由Spring IoC容器实例化、组装和管理的对象,它具有可重复使用组件的意思。
与javaBean的区别
javaBean是指遵从以下规范的java类,而Bean没有具体的规范
- 所有属性为private
- 提供默认构造方法
- 提供getter和setter
- 实现serializable接口
Bean的分类
普通Bean
普通工厂Bean
静态工厂Bean
Bean作用范围
Bean的作用范围就是指多例模式和单例模式, bean 标签里面的scope属性用于设置bean的范围
scope属性值
- singleton
单例,该属性值为默认属性 - prototype
多例 - request
作用于web应用的请求范围 - session
作用于web应用的会话范围 - global-session
作用于集群环境的会话范围,当不是集群环境时,它就是session
Bean生命周期
Bean的生命周期是指从Bean对象创建到销毁的过程
单例对象的生命周期
单例对象的生命周期和容器的生命周期相同
多例对象的生命周期
当获取多例对象时多利对象出生,在使用过程中一直活着,当多利对象长时间不用时由java垃圾回收机制回收死亡。
IOC
IOC是指把对象的创建和对象之间调用的过程都交给Spring进行管理过程。换句话说就是把我们创建好的Bean交给IOC容器,让它帮我们管理Bean。而Bean们之间的依赖由依赖注入这一过程实现。所以IOC是由IOC容器和依赖注入组成的控制反转过程。
IOC容器
IOC容器底层使用工厂模式实现的一个Bean工厂
IOC容器接口
为了使用这个IOC容器,我么就得使用spring提供的接口,spring为此提供了两个接口,这两个接口功能相似。
BeanFactory接口
此接口是IOC容器最基本的实现,是Spring内部的使用接口,不建议开发人员使用。它的特点是在加载配置文件时不创建对象,在获取对象时才会创建对象。
ApplicationContext接口
此接口是BeanFactory接口的子接口,提供了更强大的功能,是面向我们开发人员的。它的特点是在加载配置文件时就创建对象,它有以下三个常用的实现类。
ClassPathXmlApplicationContext类
- 它可以加载类路径下的配置文件,不在的加载不了
FileSystemXmlApplicationContext类
- 它可以加载磁盘任意路径下的配置文件,权限不够的加载不了
AnnotationConfigApplicationContext类
- 它用于读取注解创建容器
注册Bean
当我们写好了一个Bean类我们要在spring的配置文件中注册该Bean也就是交给Spring管理
使用默认构造函数创建
- 使用标签
< bean > - 标签位置
位于< 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
- 标签内的属性
id:bean的名字
class:bean的类路径
factory-bean:指定工厂bean的id
factory-method:指定用于创建对象的方法
使用某个工厂的方法注册bean
第一步
先将工厂类注册
<bean id="beanfactory" class="xxx.xxx.xxx"></bean>
第二步
指明方法
<bean id="bean" factory-bean="beanfactory" factory-method="xxxx"></bean>
使用静态工厂中的静态方法注册bean
<bean id="beanfactory" class="xxx.xxx.xxx" factory-method="xxxxx"></bean>
依赖注入
IOC容器的作用是是管理Bean,而依赖注入是指Bean之间依赖维护的过程
注入的数据类型
- 基本类型和String
- 集合类型
- 其他类型
注入方式
使用构造函数注入
基于xml
- 使用标签
< constructor-arg > - 标签位置
< bean >标签内部 - 标签中的属性
type:用于指定注入数据的数据类型,该数据类型也是构造函数中某个或某些参数类型
index:用于指定注入数据在构造函数中参数列表中的索引,从0开始
name:用于指定注入属性在构造函数参数列表中的名字
value:注入的数据值
ref:与之关联的Bean对象
优点
在获取bean对象时,注入数据是必须的操作,否则不能创建对象
缺点
改变了bean对象的实例化方式,我们在创建对象时,如果用不到这些数据也必须提供。所以在实际开发中使用的很少。
使用set方法注入
基于xml
- 使用标签
< property > - 标签位置
< bean >标签内部 - 标签中的属性
name:用于指定注入数据所调用的set方法名如set方法名为setName,那么该属性值为name
value:注入的数据值
ref:与之关联的Bean对象
复杂类型注入
<property name="myArray">
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>
<property name="myList">
<list>
<value>qqq</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<property name="myMap">
<map>
<entry key="1" value="hh"></entry>
<entry key="2">
<value>www</value>
</entry>
</map>
</property>
<property name="mySet">
<set>
<value>haha</value>
<value>hsdh</value>
<value>sadsa</value>
</set>
</property>
<property name="myProperties">
<props>
<prop key="key">value</prop>
</props>
</property>
优点
创建对象没有明确的限制,可以直接使用默认构造函数
缺点
如果某个成员必须有值,那么无法保证一定注入
完全注解开发
用于替代xml的注解
@Configuration
- 作用:指定当前类是一个配置类
- 注意:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写
@ComponentScan
- 作用:用于指定spring在创建容器时需要扫描的包,多个包用数组表示
属性
value
指定要扫描的包
value/basePackages
指定创建容器时要扫描的包
@Bean
- 作用:把当前方法的返回值当作bean存入到IOC容器中
- 注意:当使用注解配置方法时如果方法有参数,spring会容器中查找有没有可用的bean对象,超找的方式和@Autowired的作用是一样的.
属性
name
用于指定bean的id,不写时为当前方法的名称
@Import
- 作用:用于导入其他的配置类,使用该注解的类是主配置类,其他为子配置类
属性
value
指定其他配置类的字节码
@PropertySource
- 作用:用于指定要使用的properties文件
- 关键字:classpath表示类路径下
属性
value
指定配置文件路径
用于创建对象的注解
相当于:
<bean id="" class="">
@Component
把当前对象存入IOC容器中
属性
value
用于指定bean的id,当我们不写时默认是当前类名首字母小写
@Controller @Service @Repository
它们的作用与@Component完全一样,他们三个是spring提供的三层架构使用的注解,可以使我们的结构层次更加清晰.
- @Controller用于表现层
- @Service用于业务层
- @Repository用于持久层
用于注入数据的
相当于:
<property name="" ref="">
<property name="" value="">
基本数据类型和String
@Value
- 作用: 用于注入基本类型和String类型
- 出现位置:成员上或方法上
属性
value
用于指定数据的值,可以使用spEL表达式**${ }**
其他bean类型
@Autowired
- 作用:自动按照类型注入,只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功.如果有多个bean匹配时首先按照类型区分,然后再用变量名称作为与id的区分
- 出现位置:可以在成员上也可以在方法上
- 在使用注解注入时Set方法就不是必须的了
@Qualifier
- 作用:按照类型注入的基础之上再按照名称注入,
- 出现位置:在成员上时不能单独使用,必须和@Autowired一起使用,用在方法时可以单独使用
- 作用类型:其他bean类型,基本类型和String类型无法使用
属性
value
用于指定注入bean的id
@Resource
- 作用:直接按照bean的id注入,可以独立使用
- 出现位置:成员上或方法上
属性
name
指定bean的id
集合类型
用于改变bean作用范围的
相当于:
<bean id="" class="" scope="">
@Scope
作用:用于指定bean的作用范围
属性
value
用于指定范围的取值
- singleton
- prototype
- request
- session
- globalsession
和bean的生命周期相关的
相当于:
<bean id="" class="" init-method="" destroy-method="" />
@PostConstruct
- 作用:用于指定初始化方法
@PreDestroy
- 作用:用于指定bean销毁方法
Spring整合Junit
第一步:导入坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
第二步:使用Junit提供的注解替换main方法
@RunWith(SpringJUnit4ClassRunner.class)
第三步:告知Spring运行器ioc的创建是基于xml还是基于注解的
- @ContextConfiguration
classes属性:指定注解类所在的位置
Locations属性:指定xml文件的位置
AOP
什么是Aop
全称是 Aspect Oriented Programming 即:面向切面编程,简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。
AOP的相关术语
- Joinpoint(连接点)
所谓连接点是指那些被拦截到的点。在 spring中,这些点指的是方法,因为 spring 只支持方法类型的连接点。 - Pointcut(切入点):
所谓切入点是指我们要对那些 Joinpoint 进行拦截的定义。 - Advice(通知/增强):
所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。 - Introduction(引介):
引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field。 - Target(目标对象):
代理的目标对象。 - Weaving(织入):
是指把增强应用到目标对象来创建新的代理对象的过程。spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。 - Proxy(代理):
一个类被 AOP 织入增强后,就产生一个结果代理类。 - Aspect(切面):
是切入点和通知(引介)的结合
切入点表达式
切入点表达式的作用是指定切入点,也就是指定对哪些方法进行增强
语法
关键字
execution(表达式)
表达式
- 访问修饰符 返回值 包名…类名.方法名(参数列表)
通配写法
- 访问修饰符
可以省略 - 返回值
可以使用*号,表示任意返回值 - 包名
可以使用*号,表示任意包,但是有几级包,需要写几个 *
使用…来表示当前包,及其子包 - 类名
可以使用*号,表示任意类 - 方法名
可以使用*号,表示任意方法 - 参数列表可以直接写数据类型,基本类型直接写名称,引用类型使用包名.类名的方式
可以使用*,表示参数可以是任意数据类型,但是必须有参数
可以使用…表示有无参数均可,有参数可以是任意类型 - 全通配方式:
* *..*.*(..)
配置AOP
开始
< aop:config >
- 作用:开始aop配置
配置切面
< aop:aspect: >
- 属性
id:给切面提供一个唯一标识。
ref:引用配置好的通知类 bean 的 id。
配置切入点表达式
< aop:pointcut >
- 属性
expression:用于定义切入点表达式。
id:用于给切入点表达式提供一个唯一标识
配置对应的通知类型
<aop:before >
- 作用:
用于配置前置通知。指定增强的方法在切入点方法之前执行 - 属性:
method:用于指定通知类中的增强方法名称
ponitcut-ref:用于指定切入点的表达式的引用
poinitcut:用于指定切入点表达式 - 执行时间点:
切入点方法执行之前执行
< aop:after-returning>
- 作用:
用于配置后置通知 - 属性:
method:指定通知中方法的名称。
pointct:定义切入点表达式
pointcut-ref:指定切入点表达式的引用 - 执行时间点:
切入点方法正常执行之后。它和异常通知只能有一个执行
< aop:after-throwing>
- 作用:
用于配置异常通知 - 属性:
method:指定通知中方法的名称。
pointct:定义切入点表达式
pointcut-ref:指定切入点表达式的引用 - 执行时间点:
切入点方法执行产生异常后执行。它和后置通知只能执行一个3!
< aop:after> - 作用:
用于配置最终通知 - 属性:
method:指定通知中方法的名称。
pointct:定义切入点表达式
pointcut-ref:指定切入点表达式的引用 - 执行时间点:
无论切入点方法执行时是否有异常,它都会在其后面执行。
< aop:around >
- 作用:
用于哦配置环绕通知 - 属性:
method:指定通知中方法的名称。
pointct:定义切入点表达式
pointcut-ref:指定切入点表达式的引用 - 说明:
它是 spring 框架为我们提供的一种可以在代码中手动控制增强代码什么时候执行的方式。 - 注意:
通常情况下,环绕通知都是独立使用的,spring 框架为我们提供了一个接口:ProceedingJoinPoint,它可以作为环绕通知的方法参数。在环绕通知执行时,spring 框架会为我们提供该接口的实现类对象,我们直接使用就行。
public Object beforePrintLog(ProceedingJoinPoint pjo){
Object returnValue=null;
try {
Object [] orgs=pjo.getArgs();
System.out.println("前置");
returnValue=pjo.proceed(orgs);
System.out.println("后置");
return returnValue;
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("异常");
}finally {
System.out.println("最终");
}
return returnValue;
}
完全注解开发
@EnableAspectJAutoProxy
- 作用:开启 spring 对注解 AOP 的支持
@Aspect
- 作用:
把当前类声明为切面类
@Before
- 作用:
把当前方法看成是前置通知。 - 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@AfterReturning
- 作用:
把当前方法看成是后置通知。 - 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用
@AfterThrowing
- 作用:
把当前方法看成是异常通知。 - 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用
@After
- 作用:
把当前方法看成是最终通知。 - 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用
@Around
- 作用:
把当前方法看成是环绕通知。 - 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@Pointcut
- 作用:
指定切入点表达式 - 属性:
value:指定表达式的内容
@Pointcut("execution(* *..*.*(..))")
private void pt1(){};
JDBCTemplate和Spring声明式事务管理
主配置类
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.chinesecooly")
@EnableTransactionManagement
public class ApplicationConfiguration {
@Bean("jdbcTemplate")
public JdbcTemplate getJdbcTemplate(@Qualifier("dataSourceTransactionManager") DataSourceTransactionManager dstm){
JdbcTemplate jt=new JdbcTemplate();
jt.setDataSource(dstm.getDataSource());
return jt;
}
@Bean("dataSource")
public DriverManagerDataSource getDataSource(){
DriverManagerDataSource ds=new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/test");
ds.setUsername("root");
ds.setPassword("ny02164215");
return ds;
}
@Bean("dataSourceTransactionManager")
public DataSourceTransactionManager getDateSourceTransactionManager(@Qualifier("dataSource") DriverManagerDataSource ds){
return new DataSourceTransactionManager(ds);
}
}
在需要事务管理的地方加上
@Transactional(propagation = Propagation.REQUIRED,readOnly = false)
总结
抓紧时间
共有条评论 网友评论