1、官网
https://docs.spring.io/spring/docs/5.2.5.RELEASE/spring-framework-reference/core.html#spring-core
2、idea中设置spring的绿叶子标志
2.1、在xml文件的右上角会有 config application context的提示
2.2、project structure -modules - spring添加
3、写在xml里面。可以解压jar包或war包,来修改xml文件,而class文件无法修改!!!!!!!!!
4、IOC创建对象的方式
4.1、默认使用无参构造方法创建对象
//类型 类型名 = new 类型()
//id 类型名
ref 引用容器中创建好的对象
name 也是别名
<bean id="teacher" class="spring.Teacher" name="t1 t2,t3;t4">
<property name="name" value="lisi"/>
<property name="student" ref="student"/>
</bean>
4.2、使用有参构造创建对象
-->
<!--下标赋值 -->
<bean id="student" class="spring.Student">
<constructor-arg index="0" value="zhangsan"/>
</bean>
<bean id="teacher" class="spring.Teacher">
<constructor-arg index="0" value="lisi"/>
<constructor-arg index="1" ref="student"/>
</bean>
<!--通过类型创建,不建议使用 -->
<bean id="student" class="spring.Student">
<constructor-arg type="java.lang.String" value="zhansan"/>
</bean>
<bean id="teacher" class="spring.Teacher">
<constructor-arg type="java.lang.String" value="lisi"/>
<constructor-arg type="spring.Student" ref="student"/>
</bean>
<!--直接通过参数名设置 -->
<bean id="student" class="spring.Student">
<constructor-arg name="name" value="zhangsan"/>
</bean>
<bean id="teacher" class="spring.Teacher">
<constructor-arg name="name" value="lisi"/>
<constructor-arg name="student" ref="student"/>
</bean>
5、spring配置
5.1、别名
<alias name="student" alias="student2"/>
5.2、import 一般用于团队开发使用,将多个配置文件,导入合并成一个
<import resource="beans2.xml"/>
6、依赖注入
6.1、构造器注入
6.2、set注入
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性,由容器注入
*set注入中,name里的值对应setTeacher方法,set后面的字符串
<bean id="friend" class="spring.Friend">
<property name="name" value="wanger"/>
<property name="teacher" ref="teacher"/>
<!--数组注入 -->
<property name="books">
<array>
<value>红楼梦</value>
<value>水浒传</value>
</array>
</property>
<property name="hobbys">
<list>
<value>唱歌</value>
<value>打球</value>
</list>
</property>
<property name="card">
<map>
<entry key="省份中" value="1111"/>
<entry key="地址" value="2222"/>
</map>
</property>
<property name="games">
<set>
<value>LOL</value>
<value>MSG</value>
</set>
</property>
<property name="info">
<props>
<prop key="nn">2</prop>
<prop key="n2">3</prop>
</props>
</property>
</bean>
6.3、拓展方式注入
头文件添加
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<bean id="student" class="spring.Student" c:name="zhangsan1">
</bean>
<!--p命名空间注入,可直接注入属性的值 -->
<bean id="teacher" class="spring.Teacher" p:age="11">
<constructor-arg name="name" value="lisi"/>
<constructor-arg name="student" ref="student"/>
</bean>
7、bean的作用域
作用域 | 描述 |
singleton | 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。 |
prototype | 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。 |
request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。 |
session | 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。 |
application | 限定一个Bean的作用域为ServletContext 的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。 |
7.1、singleton 默认
<bean id="friend" class="spring.Friend" scope="singleton">
Friend friend1 = (Friend) context.getBean("friend");
Friend friend2 = (Friend) context.getBean("friend");
System.out.println(friend1 == friend2); //true
7.2、prototype, 每次从容器get,都会产生一个新的对象
<bean id="friend" class="spring.Friend" scope="prototype">
8、bean的自动装配
8.1、byname会在上下文中查找和set方法后面的字符相同的beanid
8.2、byname会在上下文中查找和自己对象属性类型相同的beanid,但必须保证该类型的bean全局唯一
<bean id="cat" class="spring.Cat" autowire="byName">
public class Cat {
private Student stu;
private Teacher tea;
public void setStudent(Student stu) {
this.stu = stu;
}
public void setTeacher(Teacher tea) {
this.tea = tea;
}
}
8.3、使用注解实现自动装配
8.3.1、导入约束
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
8.3.2、配置注解的支持 <context:annotation-config />
8.3.3、@autowired (可以在属性上用(不需要set方法),也可以在set方法上用)默认byType,同类型数大于1再根据名 字(或者说是:先byname再bytype?) 有属性 required=false
@Qualifier("student2"),如果定义了多个同类型的bean,使用@autowired会报错,需联合@Qualifier使用
@resource java的注解,默认byname,如果匹配不到名字,就bytype,有个name=“”属性指定名称;---如果指定了name或type,就按照名字或者类型完全匹配,找不到,或者找到多个,就抛异常。
@value("zhangsan") 相当于<property name="" value=""/>基本类型属性注入
9、spring的注解开发
在spring4注解开发,必须导入aop的包
<!--指定要扫描的包,这个包下面的注解就会生效 -->
<context:component-scan base-package="spring.comp"/>
@component 组件,放在类上,说明这个类被spring管理了,就是bean
@scope("singleton")
10、使用java的方式配置spring
完全不使用xml:@configuration+@bean进行配置, 这种不需要 @ComponentScan
@configuration也会被spring容器托管,注册到容器中,因为他本身也有个@component,类似bean.xm
@ComponentScan(basePackages = "spring.comp") 类似<context:component-scan base-package="spring.comp"/>
@Import(JavaConfig2.class) 相当于 <import resource="beans2.xml"/> --注意:可以导入任何类,不要求必须表@component给springioc
--2021.6.6
@import如何使用?
两种导入bean的方式
静态导入:直接指定要注入的 bean
- 普通Java类
- @Configuration 配置类
动态导入:运行时再决定注入的 bean,有点点反射的味道
- 实现 ImportSelector 接口
- 实现 ImportBeanDefinitionRegistrar 接口
----
@bean,注册一个bean,相当于bean标签,方法名相当于id,返回类型相当于class
测试方式 new AnnotationConfigApplicationContext(JavaConfig.class)
11、加载配置文件,其实就是注册一个bean
<!--读取配置文件-->
<context:property-placeholder location="classpath:"/>
等价于
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:conf/sqlmap/jdbc.properties</value>
<value>classpath:dubbo.properties</value>
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
12、PathMatchingResourcePatternResolver继承了ResourcePatternResolver
12.1、PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
String locationPattern = "classpath:" + GROOVY_SRC_FOLDER + File.separator + fileName + GROOVYSUBFIX;
Resource resource = resolver.getResource(locationPattern);
//location = classpath:xxx+File.separator+xxx
public Resource getResource(String location) {
ResourceLoader resourceLoader = new DefaultResourceLoader();
return resourceLoader.getResource(location);
//resourceLoader.getResource(location)
if (location.startsWith("classpath:")) {
return new ClassPathResource(location.substring("classpath:".length()), this.getClassLoader());
}
}
12.2、Resource[] resources = resolver.getResources("classpath*:workflow/*.json");
- idea返回鼠标上次所在位置 ctrl+alt+方向键
13、当用户使用容器本身时,可以使用转义字符”&”来得到FactoryBean本身,以区别通过FactoryBean产生的实例对象和FactoryBean对象本身
MyFactoryBean myFactoryBean = (MyFactoryBean)context.getBean("myFacoryBean");
14、@value
@Value("#{person.name}") 注入其它Bean的属性:Person类的name属性
${}表示占位符
需要注解 <context:annotation-config /> 会自动注册组件 AutowiredAnnotationBeanPostProcessor
关于反射:class.getFields():所有可访问的公共字段 ,包含超类
class.getDeclaredFields():所有声明的字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。
filed.getDeclaredAnnotations():返回直接存在于元素上的所有注释,忽略继承的注释
annotation.getAnnotationType()==Value.Class()
获取注解的值:
Class<Cat> c = Cat.class;
Field f = c.getDeclaredField("name");
Annotation[] as = f.getAnnotations();
for (Annotation a : as) {
if (a.annotationType() == Value.class) {
Method m = a.annotationType().getMethod("value");
System.out.println(m.invoke(a));
}
}
<!--读取配置文件-->
<context:property-placeholder location="classpath:spring/application.properties"/>
会注册组件 PropertySourcesPlaceholderConfigurer
15、Java环境变量(Env)和系统属性(Property)
System.getEnv() ,返回的变量大多与操作系统有关,没有set方法
Map<String, String> getenv = System.getenv();
getenv.forEach((key, value) -> {
System.out.println(key + " - " + value);
});
USERPROFILE :用户目录
USERDNSDOMAIN :用户域
PATHEXT :可执行后缀
JAVA_HOME :Java安装目录
TEMP :用户临时文件目录
SystemDrive :系统盘符
ProgramFiles :默认程序目录
USERDOMAIN :帐户的域的名称
ALLUSERSPROFILE :用户公共目录
SESSIONNAME :Session名称
TMP :临时目录
Path :path环境变量
CLASSPATH :classpath环境变量
PROCESSOR_ARCHITECTURE :处理器体系结构
OS :操作系统类型
PROCESSOR_LEVEL :处理级别
COMPUTERNAME :计算机名
Windir :系统安装目录
SystemRoot :系统启动目录
USERNAME :用户名
ComSpec :命令行解释器可执行程序的准确路径
APPDATA :应用程序数据目录
System.getProperty返回的变量大多与java程序有关,允许setProperty()自己设置系统属性
Properties properties = System.getProperties();
properties.forEach((key, value) -> {
System.out.println(key + " - " + value);
});
java.version Java :运行时环境版本
java.vendor Java :运行时环境供应商
java.vendor.url :Java供应商的 URL
java.home :Java安装目录
java.vm.specification.version: Java虚拟机规范版本
java.vm.specification.vendor :Java虚拟机规范供应商
java.vm.specification.name :Java虚拟机规范名称
java.vm.version :Java虚拟机实现版本
java.vm.vendor :Java虚拟机实现供应商
java.vm.name :Java虚拟机实现名称
java.specification.version:Java运行时环境规范版本
java.specification.vendor:Java运行时环境规范供应商
java.specification.name :Java运行时环境规范名称
java.class.version :Java类格式版本号
java.class.path :Java类路径
java.library.path :加载库时搜索的路径列表
java.io.tmpdir :默认的临时文件路径
java.compiler :要使用的 JIT编译器的名称
java.ext.dirs :一个或多个扩展目录的路径
os.name :操作系统的名称
os.arch :操作系统的架构
os.version :操作系统的版本
file.separator :文件分隔符
path.separator :路径分隔符
line.separator :行分隔符
user.name :用户的账户名称
user.home :用户的主目录
user.dir:用户的当前工作目录
***这两个,比properties文件中设置的优先级高
16、SPEL
#{ systemProperties['user.dir'] } --systemEnvironment
在@value或xml中使用,需要#{}包裹
String expressionStr = "1 + 2";
ExpressionParser expressionParser = new SpelExpressionParser();
//把该表达式,解析成一个Expression对象
Expression expression = expressionParser.parseExpression(expressionStr);
//方式一:直接计算
System.out.println(expression.getValue().toString());//3
//方式二
//表达式上下文对象
//由于表达式内可能存在占位符${},所以不太适合直接getValue()
//有环境变量,就有能力处理里面的占位符 ${}
EvaluationContext context1 = new StandardEvaluationContext();
System.out.println(expression.getValue(context1).toString());
Spel的基本使用总结:
SpEL 字面量:
- 整数:#{8}
- 小数:#{8.8}
- 科学计数法:#{1e4}
- String:可以使用单引号或者双引号作为字符串的定界符号。
- Boolean:#{true}
SpEL引用bean , 属性和方法:
- 引用其他对象:#{car}
- 引用其他对象的属性:#{car.brand}
- 调用其它方法 , 还可以链式操作:#{car.toString()}
- 调用静态方法静态属性:#{T(java.lang.Math).PI}
SpEL支持的运算符号:
- 算术运算符:+,-,*,/,%,^(加号还可以用作字符串连接)
- 比较运算符:< , > , == , >= , <= , lt , gt , eg , le , ge
- 逻辑运算符:and , or , not , |
- if-else 运算符(类似三目运算符):?:(temary), ?:(Elvis)
- 正则表达式:#{admin.email matches ‘[a-zA-Z0-9._%±]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}’}
@Value("#{'${prdtcenter.annex.type}'.split(',')}")
private List<Integer> annexTypeList;
17、beanpostprocessor
方法 | 说明 |
---|---|
postProcessBeforeInitialization | 实例化、依赖注入完毕, 在调用显示的初始化之前完成一些定制的初始化任务 |
postProcessAfterInitialization | 实例化、依赖注入、初始化完毕时执行 |
18、spring的生命周期
(1)、创建bean的实例
(2)、为bean的属性设置值或对其他bean的引用
(3)、调用aware接口的方法(beannameaware的setnameaware方法、BeanClassLoaderAware的setBeanClassLoader方法、BeanFactoryAware的setBeanFactory方法、ApplicationContextAware的setApplicationContext()方法)
(4)、调用BeanPostProcessor的预初始化方法postProcessBeforeInitialization
(5)、调用InitializingBean的afterPropertiesSet()方法
(6)、调用自定义的初始化方法
(7)、调用BeanPostProcessor的postProcessAfterInitialization()方法
(8)、容器销毁:调用DisposableBean的destroy()方法、自定义的销毁方法
19、bean指定初始化和销毁方法
(1)、@Bean(initMethod = "", destroyMethod = "")
(2)、实现InitializingBean 实现DisposableBean
(3)、使用JSR250 @PostConstruct @PreDestroy
(4)、使用beanpostprocessor,在bean初始化前后进行一些处理工作
(5)、bean标签 <bean id="cat" class="spring.Cat" init-method="" destroy-method=""/>
20、spring xml配置5种自动装配 <bean id="friend" class="spring.Friend" scope="prototype" autowire="">
(1)、no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。
(2)、byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。
(3)、byType:通过参数的数据类型进行自动装配。
(4)、constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。
21、使用@autowired注解自动装配的过程
<context:annotation-config /> 在启动spring ioc时,容器自动装载一个autowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到 @autowired @Resource() JSR250 @Inject() JSR330,就会在IOC容器自动查找需要的bean,并装配给该对象的属性。
22、@PropertySource(value={"classpath:xxl.properties"})
类似<context:property-placeholder location="classpath:spring/application.properties"/>
可以使用 ConfigurableEnvironment environment = context.getEnvironment();