Spring
第一章Spring是什么?
- 一个Java开发的轻量级框架,可以在J2SE、J2EE项目中使用
- 实现解耦合,对象之间,模块之间
- Spring核心技术:IoC,AOP
- 也叫容器,装的是Java对象
第二章IoC控制反转
2.1概念
IoC(Inversion of Control):控制反转,是一个理论,一个指导思想。指导开发人员如何使用对象,管理对象的。把对象的创建,属性赋值,对象的声明周期都交给代码之外的容器管理。
2.2IoC分为控制和反转
- 控制:对象创建,属性赋值,对象声明周期管理
- 反转:把开发人员管理对象的权限转移给了代码之外的容器实现。由容器完成对象的管理。
- 正转:开发人员在代码中,使用new构造方法创建对象。**开发人员掌握了对象**的创建,属性赋值,对象从开始到销毁的全部过程。开发人员有对对象全部控制。
通过容器,可以使用容器中的对象(容器已经创建了对象,对象属性赋值了,对象也组装好了)
Spring就是一个容器,可以管理对象,创建对象,给属性赋值。
2.3 IoC的技术实现
- DI(依赖注入 Dependency Injection) :,**缩写是DI是IoC的一种技术实现。**程序只需要提供要使用的对象的名称就可以了,对象如何创建,如何从容器中查找,获取 都由容器内部自己实现。
- Spring框架使用DI实现IoC,只需提供对象名字就可以从容器中获取对象,Spring底层通过反射创建对象,赋值属性。
2.4 配置文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-twNOdwtL-1666580281837)(…/…/…/…/PJY_WorkSpace/Typora/images/image-20220916193448602.png)]
2.5 创建Spring容器
创建Spring容器,容器创建之后里面所有对象也会创建。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
spring根据id, class创建对象,把对象放入到spring的一个map对象。map.put(id,对象)
<bean id="someService" class="com.pjy.service.impl.SomeServiceImpl"/>
2.6 基础xml的DI(依赖注入)
实现方法有:
-
set注入
-
构造注入
简单类型set注入
- 必须有set方法
- 直接给基本数据类型赋值
<!-- 简单类型set注入
<bean id="XXX" class="XXX">
<property name='属性' value='值'>
</bean> -->
<bean id="student" class="com.pjy.pojo.student">
<property name="name" value="dl"/>
<property name="age" value="19"/>
</bean>
引用类型set注入
<!-- 引用类型set注入
<bean id="XXX" class="XXX">
<property name='属性' ref='bean的id'>
</bean> -->
<bean id="school" class="com.pjy.pojo.School">
<property name="name" value="实验中学"/>
</bean>
<bean id="student1" class="com.pjy.pojo.Student">
<property name="name" value="李四"/>
<property name="school" ref="school"/>
</bean>
构造注入
- 使用name,对象属性 推荐!
<!-- 构造注入
<constructor-arg name="带参构造的形参名" value="值"/>
<constructor-arg name="带参构造的形参名" ref="引用值"/>-->
<bean id="student2" class="com.pjy.pojo.Student">
<constructor-arg name="age" value="19"/>
<constructor-arg name="name" value="dl3"/>
<constructor-arg name="school" ref="school"/>
</bean>
- 使用index,参数位置
<bean id="student2" class="com.pjy.pojo.Student">
<constructor-arg index="0" value="张三"/>
<constructor-arg index="1" value="26"/>
<constructor-arg index="2" ref="myschool"/>
</ bean>
-
省略index
引用类型自动注入(也是调用set方法)
概念: spring可以根据某些规则给引用类型完成赋值。只对引用类型有效。规则byName, byType.
- byName(按名称注入): java类中引用类型属性名称和spring容器中bean的id名称一样的,且数据类型也是一样的,这些bean能够赋值给引用类型。
- byType(按类型注入):java类中引用类型的数据类型和spring容器中bean的class值是同源关系的,这样的bean斌值给引用类型。
byName(按名称注入):
<!-- 引用类型set注入
<bean id="XXX" class="XXX">
<property name='属性' ref='bean的id'>
</bean> -->
<bean id="school" class="com.pjy.pojo.School">
<property name="name" value="清华"/>
</bean>
<!-- 依赖根据名字自动注入 对象中的属性名要和容器中的id一致-->
<bean id="student3" class="com.pjy.pojo.Student" autowire="byName">
<property name="name" value="李四"/>
</bean>
2.byType(按类型注入):
java类中引用类型的数据类型和bean的class是同源的这些的bean能够赋值给引用类型。
同源关系:
- java中引用类型的数据类型和bean的class值是一样的。
- java中引用类型的数据类型和bean的class值是父子类关系的。
- java中引用类型的数据类型和bean的class值是接口和实现类关系的。
<!-- 依赖根据数据类型自动注入 符合条件的对象只有一个-->
<bean id="student4" class="com.pjy.pojo.Student" autowire="byType">
<property name="name" value="李四"/>
</bean>
2.7 基于注解的DI(依赖注入)
1 @component:表示创建对象,对象放到容器中。作用是<bean>
属性: value ,表示对象名称,也就是bean的id属性值位置:在类的上面,表示创建此类的对象。
@component (vaLue = “mystudent”)等同于
<bean id=“mystudent” class="com. bjpowernode.ba01.student”/>
<!--声明组件扫描器:使用注解必须加入这个语句
component-scan:翻译过来是组件扫描器,组件是java对象。
属性: base-package注解在你的项目中的包名。
框架会扫描这个包和子包中的所有类,找类中的所有注解。
遇到注解后,按照注解表示的功能,去创建对象,给属性赋值。-->
<context : component-scan base-package="com.bjpowernode .ba01"/>
2 @Component功能相同的创建对象的注解。
- @Repository :放在dao接口的实现类上面,表示创建dao对象,持久层对象,能访问数据库
- @service :放在业务层接口的实现类上面,表示创建业务层对象,业务层对象有事务的功能
- @controlLer:放在控制器类的上面,表示创建控制器对象。属于表示层对象。控制器对象能接受请求,把请求的处理结果显示给用户。
3 基本数据类型注入 @Value(“xx”)
位置:
- 在属性定义的上面,无需set方法,推荐使用
- 在set方法的上面
4 引用类型数据注入@Autowired:
- spring框架提供的,给引用类型赋值的,使用自动注入原理。支持byName,byType。默认是byType.
- 属性: required : boolean类型的属性,默认true
- true: spring在启动的时候,创建容器对象时候,会检查引用类型是否赋值成功。如果赋值失败,终止程序执行,并报错。
- false:引用类型赋值失败,程序正常执行,不报错。引用类型的值是null
- @Autowire+@Qualifier(“ID”) 可注入指定依赖
5 @Repository
-
来自jdk中,给引用类型赋值的,支持byName, byType.默认是byName spring支持这个注解的使用。
-
使用位置:
- 在属性定义的上面,无需set方法,推荐使用
- 在set方法的上面
-
说明,使用jdk1.8带有@Resource注解,高于jdk1.8没有这个@Resource,需要加入一个依赖。
<dependency>
<groupId>javax. annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
2.8 Spring管理多配置文件
分多个配置文件的方式:
- 按功能模块分,一个模块一个配置文件。
- 按类的功能分,数据库操作相关的类在一个文件, service类在一个配置文件,配置redis,事务等等的一个配置文件。
spring管理多个配置文件:常用的是包含关系的配置文件。项目中有一个总的文件,里面是有impor标签包含其他的多个配置文件。
语法:
总的文件〈xm1)
<import resource="其他的文件的路径1"/>
<import resource="其他的文件的路径2"/>
关键字"classpath:":表示类路径,也就是类文件(class文件)所在的目录。
spring到类路径中加载文件什么时候使用classpath:在一个文件中要使用其他的文件,需要使用classpath
第三章 AOP面向切面编程
3.1 什么是AOP?
AOP(Aspect Orient Programming):面向切面编程
Aspect:表示切面,给业务方法增加的功能,叫做切面。切面一般都是非业务功能,而且切面功能一般都是可以复用的。例如日志功能,事务功能,权限检查,参数检查,统计信息等等。
AOP是一种动态思想,在程序运行中创建代理,给切面增加功能,代理对象只存在内存。
使用AOP在不修改源码的情况下给业务代码增加非业务功能
对切面的理解:把业务代码切开,插入非业务代码,在不动源代码的情况下加强功能
3.2 AOP中的术语
- Aspect:切面,给业务方法增加的功能。
- JoinPoint:连接点,一个连接切面的业务方法。在这个业务方法执行时,会同时执行切面的功能。
- Pointcut:切入点,是一个或多个连接点集合。表示这些方法执行时,都能增加切面的功能。表示切面执行的位置。
- target:目标对象,给那个对象增加切面的功能,这个对象就是目标对象。
- Advice:通知(增强),表示切面的执行时间。在目标方法之前执行切面,还是目标方法之后执行切面。
AOP中重要的三个要素: Aspect,Pointcut , Advice.这个概念的理解是:在Advice的时间,在Pointcut的位置,执行Aspect
3.3 AspectJ框架实现AOP
导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
3.3.1相关注解
Aspectj表示切面执行时间,用的通知(Advice)。这个通知可以使用注解表示。讲5个注解,表示切面的5个执行时间,这些注解叫做通知注解。
- @Aspect:作用是把当前类标识为一个切面供容器读取
- @Before :前置通知
- @AfterRetunring:后置通知
- @Around:环绕通知
- @AfterThrowing:异常通知
- @After:最终通知
3.3.2.Pointcut 切入点 (execution())
Pointcut用来表示切面执行的位置,使用Aspectj中切入点表达式。
切入点表达式语法: execution(访问权限 方法返回值 方法声明 (参数) 异常类型)
例如 :
@Before:前置通知
特点:
- 执行时间:在目标方法之前先执行的。
- 不会影响目标方法的执行。
- 不会修改目标方法的执行结果。
@Aspect
@Component
public class myAspect {
@Before(value = "execution(public void com.pjy.service.Impl.UserServiceImpl.addUser(..))")
public void beforeAdd() {
System.out.println("前置增强");
}
}
属性: value 切入点表达式,表示切面的执行位置。支持通配符
3.3.3 @Pointcut定义和管理切入点注解
/**
* 不需要写代码
* 一般为私有
* 统一和管理切入点表达式
*/
@Pointcut(value = "execution(* *..UserServiceImpl.addUser(..))")
private void mypoint() {
}
@Before(value = "mypoint()")
public void beforeAdd() {
System.out.println("beforeAdd");
}
3.3.4 AOP实现流程
- 导入spring-aspects依赖,使用AspectJ实现AOP
- 完成业务功能
- 写切面类,切面类需要加上@Aspect和(标识这为一个切面类)@Component(为了放入Spring容器)
- 写切入点,在切面类的方法上加@Before(execution( ))等等 ,execution( )切入点表达式,方法切入位置
- 配置文件加上自动代理生成器 <aop:aspectj-autoproxy/>
- 配置文件加上包扫描<context:component-scan base-package=“包名”/>