Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。 目前是JavaEE开发的灵魂框架。他可以简JavaEE开发,可以非常方便整合其他框架,无侵入的进行功能增强。
Spring的核心就是 控制反转(IoC)和面向切面(AOP)
。
官网|官方下载地址|GitHub
控制反转,之前对象的控制权在类手上,现在反转后到了Spring手上。
①导入依赖
导入SpringIOC相关依赖
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.1.9.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.1.10.RELEASEversion>
dependency>
②编写一个Hello实体类
public class Hello {
private String name;
//省略get、set
public void showName(){
System.out.println("Hello,"+ name );
}
}
③编写配置文件
在resources目录下创建applicationContext.xml文件,文件名可以任意取。但是建议叫applicationContext。
<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">
<bean id="hello" class="com.yu.pojo.Hello">
<property name="name" value="奇遇少年"/>
bean>
beans>
④创建容器从容器中获取对象并测试
public class SpringTest {
public static void main(String[] args) {
//解析beans.xml文件 , 生成管理相应的Bean对象
//创建Spring容器,指定要读取的配置文件路径
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//getBean : 参数即为spring配置文件中bean的id .
//从容器中获取对象
Hello hello = (Hello) context.getBean("hello");
//调用对象的方法进行测试
hello.showName(); //Hello,奇遇少年
}
}
scope主要有两个值:singleton
和prototype
一个bean对象
。默认容器创建的时候就会创建该对象。多个该bean对象
。每次调用getBean方法获取时都会创建一个新对象。scope非主要有两个值:Request
和Session
依赖注入可以理解成IoC的一种应用场景,反转的是对象间依赖关系维护权。
在要注入属性的bean标签中进行配置。前提是该类有提供属性对应的set方法。
public class User {
private String name;
private Hello hello;
//省略get、set
}
<bean id="hello" class="com.yu.pojo.Hello">
<property name="name" value="奇遇少年"/>
bean>
<bean id="user" class="com.yu.pojo.User">
<property name="name" value="奇遇少年"/>
<property name="hello" ref="hello" />
bean>
applicationContext.xml有三种方式编写
<bean id="user" class="com.yu.pojo.User">
<constructor-arg index="0" value="奇遇少年"/>
bean>
<bean id="user" class="com.yu.pojo.User">
<constructor-arg name="name" value="奇遇少年"/>
bean>
<bean id="user" class="com.yu.pojo.User">
<constructor-arg type="java.lang.String" value="奇遇少年"/>
bean>
导入依赖
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.28version>
dependency>
创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private int age;
private String name;
private Phone phone;
private List<String> list;
private List<Phone> phones;
private Set<String> set;
private Map<String, Phone> map;
private int[] arr;
private Properties properties;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Phone {
private double price;
private String name;
private String password;
private String path;
}
配置如下:
<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">
<bean class="com.yu.pojo.Phone" id="phone">
<property name="price" value="9999">property>
<property name="name" value="华为mate 60">property>
<property name="password" value="666">property>
<property name="path" value="www">property>
bean>
<bean class="com.yu.pojo.User" id="user">
<property name="age" value="10">property>
<property name="name" value="大队长">property>
<property name="phone" ref="phone">property>
<property name="list">
<list>
<value>奇遇少年value>
<value>奇遇少女value>
list>
property>
<property name="phones">
<list>
<ref bean="phone">ref>
list>
property>
<property name="set">
<set>
<value>setEle1value>
<value>setEle2value>
set>
property>
<property name="map">
<map>
<entry key="k1" value-ref="phone">entry>
<entry key="k2" value-ref="phone">entry>
map>
property>
<property name="arr">
<array>
<value>10value>
<value>11value>
array>
property>
<property name="properties">
<props>
<prop key="k1">v1prop>
<prop key="k2">v2prop>
props>
property>
bean>
beans>
我们可以再配置文件中使用SPEL表达式。写法如下:
<property name="age" value="#{...}"/>
注意:SPEL需要写到value属性中,不能写到ref属性。
配置文件
User.java :注意:这里没有有参构造器!
public class User {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
.....
}
}
需要在头文件中加入约束文件
导入约束 : xmlns:p="http://www.springframework.org/schema/p"
<bean id="user" class="com.yu.pojo.User" p:name="奇遇少年"/>
需要在头文件中加入约束文件
导入约束 : xmlns:c="http://www.springframework.org/schema/c"
<bean id="user" class="com.yu.pojo.User" c:name="奇遇少年" />
发现问题:爆红了,刚才我们没有写有参构造!
解决:把有参构造器加上,这里也能知道,c 就是所谓的构造器注入!
测试代码:
public class SpringTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
System.out.println(user);
}
}
我们可以让Spring读取properties文件中的key/value,然后使用其中的值。
在Spring配置文件中加入如下标签:指定要读取的文件的路径。
<context:property-placeholder location="classpath:filename.properties">
其中的classpath表示类加载路径下。
我们也会用到如下写法:classpath:**.properties 其中的* * 表示文件名任意。
注意:context命名空间的引入是否正确
在我们需要使用的时候可以使用${key}来表示具体的值。注意要再value属性中使用才可以。例如:
<property name="propertyName" value="${key}"/>
alias 设置别名 , 为bean设置别名 , 可以设置多个别名
<alias name="user" alias="user01"/>
<bean id="hello" name="hello2 h2,h3;h4" class="com.yu.pojo.Hello">
<property name="name" value="奇遇少年"/>
bean>
name属性
我们可以用name属性来给bean取名。例如:
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource" name="dataSource2,dataSource3">
<property name="driverClassName" value="${jdbc.driver}">property>
<property name="url" value="${jdbc.url}">property>
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
bean>
获取的时候就可以使用这个名字来获取了
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
DruidDataSource dataSource = (DruidDataSource) app.getBean("dataSource3");
System.out.println(dataSource);
}
可以控制bean的创建时间,如果设置为true就是在第一次获取该对象的时候才去创建。
<bean class="com.alibaba.druid.pool.DruidDataSource" lazy-init="true" id="dataSource" name="dataSource2,dataSource3">
<property name="driverClassName" value="${jdbc.driver}">property>
<property name="url" value="${jdbc.url}">property>
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
bean>
可以用来设置初始化方法,设置完后容器创建完对象就会自动帮我们调用对应的方法。
<bean class="com.yu.pojo.User" id="user" init-method="init">bean>
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User{
private String name;
//初始化方法
public void init(){
System.out.println("对用户对象进行初始化操作");
}
}
注意:配置的初始化方法只能是空参的。
可以用来设置销毁之前调用的方法,设置完后容器销毁对象前就会自动帮我们调用对应的方法。
<bean class="com.yu.pojo.User" id="user" destroy-method="close">bean>
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User{
private String name;
//初始化方法
public void init(){
System.out.println("对用户对象进行初始化操作");
}
public void close(){
System.out.println("对象销毁之前调用,用于释放资源");
}
}
注意:配置的方法只能是空参的。
当我们需要让Spring容器使用工厂类来创建对象放入Spring容器的时候可以使用factory-bean和factory-method属性。
配置文件中进行配置
<bean class="com.yu.factory.CarFactory" id="carFactory">bean>
<bean factory-bean="carFactory" factory-method="getCar" id="car">bean>
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取car对象
Car c = (Car) app.getBean("car");
System.out.println(c);
配置文件中进行配置
<bean class="com.yu.factory.CarStaticFactory" factory-method="getCar" id="car2">bean>
创建容器获取对象测试
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取car对象
Car c = (Car) app.getBean("car2");
System.out.println(c);