spring
spring
spring是一个轻量级的控制反转(IOC、DI)和面向切面编程(AOP)的对象容器框架
spring官网:http://spring.io/
IOC:inversion of control
AOP:aspect oriented programming
作用:
-
方便解耦,简化开发
-
aop编程的支持
-
声明事物的支持
-
方便程序的测试
-
方便集成各种框架
spring jar包
spring-core |
框架的基础功能,包括IOC和AOP功能 |
spring-aspects |
提供了与AspectJ的集成,AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。 |
spring-beans |
所有应用都要用到,包含访问配置文件、创建和管理 bean 以及进行 Inversion of Control(控制反转) / Dependency Injection(依赖注入)操作相关的所有类。外部依赖 spring-core |
spring-context |
|
spring-aop、spring-instrument |
面向切面编程、植入代理 |
spring-expression |
模块提供了强大的表达式语言去支持查询和操作运行时对象图。这是对JSP 2.1规范中规定的统一表达式语言的扩展。该语言支持设置和获取属性值,属性分配,方法调用,访问数组,集合和索引器的内容,逻辑和算术运算,变量命名以及从Spring的IoC容器中以名称检索对象。 它还支持列表投影和选择以及常见的列表聚合。 |
spring-messaging |
消息传递 |
spring-jdbc、spring-jms、spring-orm |
数据访问支持 |
spring-jcl |
Jakarta Commons Logging采用了设计模式中的“适配器模式”,它对外提供统一的接口,然后在适配类中将对日志的操作委托给具体的日志框架。 |
spring-tx |
事务 |
spring-webmvc、spring-web |
Webmvc框架支持 |
spring-webflux |
Servlet3.1 + Netty 方式的WebMvc |
spring-websocket |
对ws支持 |
实例:
配置文件
<?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:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="Person" class="com.zrm.Person">
<constructor-arg name="name" value="zrm"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="food" ref="food"></constructor-arg>
</bean>
<bean id="food" class="com.zrm.Food">
</bean>
</beans>
package com.zrm;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class GetBean {
public static void main(String[] args) {
// 通过spring来获取一个类的控制权
// ClassPathXmlApplicationContext ctx = new
// ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ctx.getBean("Person");
// person.setAge(18);
// person.setName("zrm");
// System.out.println(person.getName());
// System.out.println(person.getAge());
System.out.println(ToStringBuilder.reflectionToString(person,ToStringStyle.MULTI_LINE_STYLE));//ToStringBuilder工具类
}
}
maven中央仓库:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zrm.springmaven</groupId> <artifactId>springm</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springm</name> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> </dependencies> </project>
spring注入方式:
-
构造器注入 constructor-arg:通过构造器注入,在bean中必须要有想对应的构造器
<constructor-arg name="name" value="zrm"></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <constructor-arg name="food" ref="food"></constructor-arg>
构造方法如下:
public Person(String name, Integer age, Food food) {
super();
this.name = name;
this.age = age;
this.food = food;
}
- 属性注入:不需要构造器,实际上是通过调用set方法来实现
package com.zrm;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Person {
//不同类型的成员变量
private String name;
private Integer age;
private Food food;
private List<Integer> list;
private Set<Integer> set;
private Map<Integer, String> map;
private Properties properties;
private String[] arr;
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
public List<Integer> getList() {
return list;
}
public void setList(List<Integer> list) {
this.list = list;
}
public Set<Integer> getSet() {
return set;
}
public void setSet(Set<Integer> set) {
this.set = set;
}
public Map<Integer, String> getMap() {
return map;
}
public void setMap(Map<Integer, String> map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public String[] getArr() {
return arr;
}
public void setArr(String[] arr) {
this.arr = arr;
}
public Person() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
<?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:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="Person" class="com.zrm.Person">
<property name="name" value="zrm"></property>
<property name="age">
<value>18</value>
</property>
<property name="food" ref="food"></property>
<property name="list">
//list集合
<list>
<value>1</value>
<value>2</value>
<value>3</value>
<value>2</value>
<value>1</value>
</list>
</property>
//set集合
<property name="set">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
<value>2</value>
<value>1</value>
</set>
</property>
<property name="map">
<map>
<entry key="1" value="first"></entry>
<entry key="2" value="food"></entry>
</map>
</property>
//Properties多属性
<property name="properties">
<props>
<prop key="1">first</prop>
<prop key="2">first2</prop>
<prop key="3">first3</prop>
<prop key="4">first4</prop>
<prop key="5">first5</prop>
<prop key="6">first6</prop>
</props>
</property>
//数组
<property name="arr">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
<value>5</value>
<value>6</value>
</array>
</property>
</bean>
<bean id="food" class="com.zrm.Food">
<property name="name" value="orange"></property>
</bean>
</beans>
-
使用p-namespace
属性注入
添加一个namespace
使用 p
<bean id="person" class="com.msb.Person" p:age="21" p:name = "zhangsan">
<bean id="person" class="com.msb.Person" p:age="21" p:name = "zhangsan" p:food-ref="food">
使用c- namespace
构造器注入
<bean id="foo" class="x.y.Foo" c:bar-ref="bar" c:baz-ref="baz" c:email= "foo@bar.com"/>
对其他bean的引用:
<property name="food" ref="food"></property>
<bean id="food" class="com.msb.Food"></bean>
-
depends-on 提前初始化
可以使某个bean在创建前,先创建别的bean
-
lazy-init
在容器启动后,bean被使用到的时候才加载。可以使用的lazy-init属性
bean id="person" class="com.msb.Person" lazy-init="false"
-
作用域
spring为bean提供了6种作用域,其中4种只有在web-aware的ApplicationContext种才有用。用户也可以创建自定义的作用域。
singleton 、prototype 、websocket、request、session、application
singleton scope 单例作用域
每一个类,在一个容器内只能产生一个实例
prototype scope 原型作用域
该bean每次被注入,或者使用getBean()方法获取时,都返回一个新的实例。
Request scope
该作用域的bean,在每个HTTP request都会新建一个实例,当一个request结束后,该实例也会被丢弃。
Session scope
某一个用户在一段时间内,会使用同一个session,session有超时时间,过了超时时间则session失效。不同用户使用不同的session。
Application scope
该作用域的bean,每一个application会创建一个 -
通过属性注入
l 循环依赖的bean都是singleton 成功
l 循环依赖的bean都是prototype 失败
l 同时有singleton和prototype 当先获取的那个bean是singleton时,就会成功,否则失败
l
当Spring容器在创建A时,会发现其引用了B,从而会先去创建B。同样的,创建B时,会先去创建C,而创建C时,又先去创建A。最后A、B、C之间互相等待,谁都没法创建成功
-
annotation注解注入
使用注解需要导入AOP包
在配置文件中添加Context约束
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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
"
>
<context:component-scan>
<context:component-scan base-package="com.msb"></context:component-scan>
component-scan可以自动扫描包内容,并注册Bean到Spring容器
@Component
在需要注册到容器的类上添加@Component标签,标识这个类由Spring容器接管
约定大于配置
在一个类上添加@Component默认会使用首字母小写的类名作为ID注册到Spring容器。
如果需要手动指定Bean Id可以使用@Component("p")
同属@Component的额外三个注解
@Controller @Service @Repository
这三个注意在MVC开发中会经常用到,除了注解名字和Component不一样之外,其余功能都一样。
Spring额外提供这三个注解的目的主要是为了区分MVC中每个类的区别。
@Scope
使用注解注册Bean 默认的作用域还是singleton,可以使用@Scope("prototype")改变对象作用域
@Value
在使用注解给对象注入值的时候,不再需要Get/Set方法
基础类型
使用@Value注解
@Value("小明")
private String name;
对象引用
@Autowired
private Pet MyPet;
使用@Autowired注解
默认是ByType的,如果需要ByName需要配合@Qualifier注解
@Autowired()
@Qualifier("p2")
private Pet MyPet;
<?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:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="person" class="com.zrm.Person" name="person3" lazy-init="false" scope="singleton"> <!--空值注入 <property name="name"><value></value></property>--> <!--空值注入 <property name="name"><null></null></property>--> <!--自动注入--> <!--<property name="age"> <value>18</value> </property>--> </bean> <!--别名--> <alias name="person" alias="person1"></alias> <alias name="person" alias="person2"></alias> </beans>