spring学习笔记
Spring
1 把对象的创建交给spring来管理
1.1 创建bean的三种方式
第一种方式:使用默认构造函数创建。在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时,此时采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
第二种方式:使用工厂中的普通方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
<bean id="Factory" class="com.itheima.factory.Factory"></bean>
<bean id="accountService" factory-bean="Factory" factory-method="getAccountService"></bean>
第三种方式:使用工厂中的静态方法创建对象(使用某个类中静态方法创建对象,并存入spring容器)
<bean id="orderFactory" class="com.qf.factory.OrderFactory" factory-method="getOrder"></bean>
1.2bean的左右范围调整
bean标签的score属性
作用:用于指定bean的作用范围
取值:常用的是单例的和多例的
1.singleton:单例的(默认的)
2.prototype:多例的
3.request:作用于web应用的请求范围
4.session:作用于web应用的会话范围
5.global-session:作用域集群环境的会话范围(全局会话范围),当不是集群环境时,就相当于session
1.3bean对象的生命周期
单例对象:
出生:当容器创建时,对象出生
活着:只要容器还在,对象一直活着
死亡:容器销毁时,对象死亡
总结:单例对象的生命周期和容器相同
多例对象:
出生:当我们使用对象时spring框架为我们创建
活着:对象只要在使用过程中就一直活着
死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收
2 . spring中的依赖注入
2.1 依赖注入 Dependency Injection
作用:依赖关系的管理,依赖都交给 spring 来维护
在当前类需要用到其他类的对象,由 spring 为我们提供,我们只需要在配置文件中说
明
2.2 IOC的作用
降低程序间的耦合(依赖关系)
2.3 能注入的数据
基本类型和String
其他bean类型(在配置文件中或者注解配置过的bean)
复杂类型/集合类型
2.4 注入的方式
第一种:使用构造函数提供
构造函数注入:
使用的标签:constructor-arg
标签出现的位置:bean标签的内部
标签中的属性:
type:用于指定要注入的数据的数据类型该数据类型也是构造函数中的某个参数或者某些参数的类型。
index:用于指定要注入的数据给给构造函数中指定索引位置的参数赋值,索引的位置是从0开始。
name:用于指定给构造函数中指定名称的参数赋值。常用的
以上三个属性用于指定给构造函数中的哪个参数赋值
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在spring的核心容器中出现过的bean对象
优势:
在获取bean对象时,注入数据是必须的操作,否则对象无法创造成功。
弊端:
改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<constructor-arg name="name" value="test"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!-- 配置一个时期对象-->
<bean id="now" class="java.util.Date"></bean>
第二种:使用set方法提供
set方法注入 更常用的方法
设计的标签:property
出现的位置:bean标签的位置
标签的属性:
name:用于指定注入时所调用的set方法名称
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在spring的核心容器中出现过的bean对象
优势:创建对象时没有明确的限制,可以直接使用默认构造函数。
弊端:如果有某个成员必须有值,则获取的对象有可能是set方法没有执行。
<bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2">
<property name="name" value="test"></property>
<property name="age" value="21"></property>
<property name="birthday" ref="now"></property>
</bean>
第三种:使用注解提供
用于创建创建对象的注解
他们的跟在XML配置文件中编写一个
@Component:
用法:定义在类名上。
作用:用于把当前类对象存入spring容器中。
属性:value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
注意:我们要在bean.xml告知spring在创建容器时要扫描的包。
<context:component-scan base-package="包名"></context:component-scan>
我们也可以自定义value属性的值。
由Component衍生的注解
@Controller:一般用在表现层。
@Service:一般用在业务。
@Repository:一般用在持久层。
以上三个注解他们的作用和属性与@Component是一模一样,他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰。
用于注入数据的注解
作用:他们的作用就和在xml配置文件中的bean标签中写一个
@Autowired:
作用:自动按照类型注入,只要容器中有唯一一个bean对象类型和要注入的变量类型匹配,就可以注入成功。
如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
如果ioc容器中有多个类型匹配时 : 首先按照类型匹配,再按照bean的名称进行匹配。
出现位置:可以是变量上,也可以是方法上。
细节:使用注解注入时,set方法注入就不是必须的了。
@Qualifier
作用:再按照类型注入的基础之上,再按照类型注入,它在给类成员注入时不能单独使用,但是在给方法参数注入时可以但单独使用。
属性: value:用于指定注入bean的id。
@Rresource
作用:直接按照bean的id注入,可以独立使用。
属性: name:用于指定bean的id。
注意 :以上三个注解都只能注入其他bean类型的数据,而基本类型和String类型无法使用上面三个注解实现,另外,集合类型的注入只能通过XML来实现。
@Value:
作用:用于注入基本类型和String类型的数据
属性:
value:用于指定数据的值,它可以使用spring中SpEl(也就是 spring中的el表达式)
SpEl的写法:$(表达式)
用于改变作用范围的注解
他们的作用就和bean标签中使用scope属性实现的功能是一样的。
@Scope :用于指定bean的作用范围 。
属性:
value:指定范围的取值,常用取值:singleton,prototype 。 (默认为singleton)
和生命周期相关的注解(了解即可)
他们的作用就和在bean标签中使用init-method和destory-method的作用是一样的。
@PreDestory:用于指定销毁方法
@PostConstruct:用于指定初始化方法
3.spring中的新注解
-
@Configuration:指定当前类是一个配置类
细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写
-
@ComponentScan:用于通过注解指定Spring在创建容器时要扫描的包
属性:
value:它和basePagekages的作用是一样的,都是用于指定创建容器时需要扫描的包。
我们使用此注解就等同于在xml中配置了context:component-scan。
-
@Bean:用于把当前方法的返回值作为bean对象存入spring的ioc容器中
属性:用于指定bean的id。不写时,,默认值是当前方法的名称。
细节:当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。查找的方法和Autowired注解的作用是一样的。
-
@Import:导入其他的配置类
属性:
value:用于指定其他配置类的字节码。当我们使用Import注解之后,有Import注解的就是父配置类,而导入的都是子配置类。
-
@PropertySource:用于指定properties文件的位置
属性:value:指定文件的名称和路径,关键字:classpath,表示内路径下·
4. spring整合Junit
4.1 配置
-
导入spring整合junit的jar
-
使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的@Runwith
-
告知spring的运行器,spring和ioc创建是基于xml还是注解的,并说明位置,
@ContextConfiguration:
locations:指定xml文件的位置,加上classpath关键字表示在类路径下。
classes:指定注解类所在位置。
当我们使用spring 5版本以上,要求junit的jar必须是4.12版本及以上版本。
5.java动态代理
5.1 特点
代理对象在程序的运行过程中创建。
5.1 作用
不修改源码的基础上对方法增强。
5.1 分类
基于接口的动态代理 jdk :
涉及的类:Proxy 提供者:JDK 官方
如何创建代理对象: 使用 Proxy 类中的 newProxyInstance 方法
创建代理对象的要求
被代理类至少实现一个接口,如果没有则不能使用。
newProxyInstance 方法的参数:
-
ClassLoader:类加载器:它是用于加载代理对象字节码的,和被代理对象使用相同的类加载器。是固定写法 (写被代理对象的类加载器)。固定写法:代理对象.getClass().ClassLoader()
-
Class[]:字节码数组 它是用于让代理对象和被代理对象有相同的方法(只要两者都实现了同一个接口, 那么两者的方法必然相同,所以我们传接口的字节码文件即可)。固定写法:代理对象.getClass().getInterfaces()
-
InvocationHandler:处理器 用于提供增强的代码,它是让我们写如何代理,我们一般都是写一个该接口的实 现类。通常情况下都是匿名内部类,但不是必须的,此接口的实现类都是谁用谁写。


基于子类的动态代理 cglib
涉及的类:Enhancer, 提供者:第三方chlib库
如何创建代理对象: 使用 Enhancer 类中的 create 方法
创建代理对象的要求:
被代理类不能是最终类
create 方法的参数:
- Class:字节码:它是用于被代理对象的字节码。固定写法:代理对象.getClass()
- Callback:处理器 用于提供增强的代码,它是让我们写如何代理,我们一般都是写一个该接口的实 现类。通常情况下都是匿名内部类,但不是必须的,此接口的实现类都是谁用谁写。一般写的都是该接口的子接口实现类:MethodInterceptor


6. AOP
6.1 AOP原理

6.2 springAop

6.3 AOP相关术语



6.4 spring中基于XML的AOP配置步骤
-
把通知bean也交给spring来管理
-
使用aop:config标签表名开始AOP的配置
-
使用aop:aspect标签表明配置切面
id属性:是给切面提供一个唯一标识
ref属性:是指定通知类bean的id
-
在aop:aspect标签的内部使用对应标签来配置通知的类型
aop:before:表示前置通知
method:用于指定该类中哪个方法是前置通知
pointcut属性:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强
切点表达式的写法:
关键字:execution
表达式:
访问修饰符 返回值 包名.包名.包名...类名.方法名(参数列表)
标注的表达式示例:
Public void com.qf.service.impl.AccountServiceImpl.saveAccount()

浙公网安备 33010602011771号