一、Spring工程的创建
1、环境预设
- Maven
- JDK1.8
- Spring5.1.7
- Idea
2、项目创建
1.使用Idea构建一个普通Maven项目
2.引入Spring5.1.7,详细看下面pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>org.wh.spring</groupId>
<artifactId>spring-vip-ioc</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
</dependencies>
</project>
3、创建Spring配置文件
在项目resources里创建applicationContext.xml,内容如下
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
二、Spring初始化的几种方式
1.默认为项目工作路径,及项目的根目录
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
2.使用前缀file,表示文件的绝对路径
ApplicationContext context = new ClassPathXmlApplicationContext("file:D:/applicationContext.xml");
3.加载多个配置文件
String[] xmlCfg = new String[] {"applicationContext.xml", "file:D:/applicationContext.xml"};
ApplicationContext context = new ClassPathXmlApplicationContext(xmlCfg);
4.通配符加载
ApplicationContext context = new ClassPathXmlApplicationContext("spring-*.xml");
5.没有前缀:默认为项目的classpath下相对路径
ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/resources/spring-1.xml");
6.使用前缀file,表示文件的绝对路径
ApplicationContext context = new FileSystemXmlApplicationContext("file:D:/spring-1.xml");
7.加载多个配置文件
String[] xmlCfg = new String[] {"file:D:/spring-1.xml", "classpath:spring-2.xml"};
ApplicationContext context = new FileSystemXmlApplicationContext(xmlCfg);
8.通配符加载
ApplicationContext context = new FileSystemXmlApplicationContext("classpath:spring-*.xml");
9.注解初始化(完成无xml化)
创建带有@Configuration的spring配置类,来代替applicationContext.xml
package org.wh.spring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.wh.spring.model.User;
@Configuration
public class SpringApplicationConfig {
@Bean("user2")
public User getUser() {
User user = new User();
user.setName("小明");
user.setAge(20);
return user;
}
}
加载测试
package org.wh.spring;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.wh.spring.config.SpringApplicationConfig;
import org.wh.spring.model.User;
/**
* 主入口
*/
public class ApplicationContextMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringApplicationConfig.class);
User user = (User) context.getBean("user2");
System.out.println(user);
System.out.println(context);
}
}
10.使用@ImportResource读取配置文件
package org.wh.spring.config;
import org.springframework.context.annotation.ImportResource;
@ImportResource("spring-1.xml")
public class SpringApplicationConfig {
}
spring-1.xml
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="order" name="order" class="org.wh.spring.model.Order">
<property name="orderNumber" value="10011001100"></property>
<property name="price" value="21.00"></property>
</bean>
</beans>
测试
package org.wh.spring;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.wh.spring.config.SpringApplicationConfig;
import org.wh.spring.model.Order;
import org.wh.spring.model.User;
/**
* 主入口
*/
public class ApplicationContextMain {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringApplicationConfig.class);
Order order = (Order) context.getBean("order");
System.out.println(order);
System.out.println(context);
}
}
类图预览
Spring提供的两种容器类型,ApplicationContext和BeanFactory区别
两者都是用来从容器中获取spring beans的,不同之处在于BeanFactory使用的是懒加载,也就是在我们通过getBean()调用它们时才会进行实例化,而ApplicationContext继承自BeanFactory,与前者不同的在于ApplicationContext在启动时就将所有beans全部实例化了
如何选择使用
因为BeanFactory是懒加载的,在调用时才能实例化,所以对内存消耗比较小,适合对资源有限情况
而ApplicationContext,在ApplicationContext启动时将所有的Bean都加载了,不需要每次调用在实例化使得应用运行速度较之更快
当然,在实际开发应用中ApplicationContext更为常用
三、基于XML的bean初始化及应用
1.Bean属性标签
-
id
bean的id,需满足XML命名规范
-
name
bean的name,与id一样,它们都是唯一性的,在配置文件中不允许出现两个
-
class
指向要初始化的类
-
property
属性赋值
-
ref
引用对象
-
constructor-arg
构造函数,例:<constructor-arg index="1" type="float" value="20.00" />
index 构造函数中第几个参数
type 数据类型,基础数据类型直接写,否则写全路径java.lang.String
value 赋值
2.Bean功能标签
-
init-method
初始化时调用的方法
-
destroy-method
销毁时调用的方法
-
Scope
对象在spring容器(IoC容器)中的生命周期,也可以理解为对象在spring容器中的创建方式
- singleton 单例模式
- prototype 原型模式
3.示例演示
User
package org.wh.spring.model;
public class User {
private String name;
private int age;
private Order order;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", order=" + order +
'}';
}
public void initMethod() {
System.out.println("-----------User类初始化方法--------------");
}
public void destroyMethod() {
System.out.println("-----------User类销毁方法--------------");
}
}
Order
package org.wh.spring.model;
public class Order {
private String orderNumber;
private float price;
public Order(String orderNumber, float price) {
this.orderNumber = orderNumber;
this.price = price;
}
public String getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
@Override
public String toString() {
return "Order{" +
"orderNumber='" + orderNumber + '\'' +
", price=" + price +
'}';
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 用户 -->
<bean id="user" name="user" class="org.wh.spring.model.User" init-method="initMethod" destroy-method="destroyMethod" scope="prototype">
<property name="name" value="小明"></property>
<property name="age" value="6"></property>
<property name="order" ref="order"></property>
</bean>
<!-- 订单 -->
<bean id="order" name="order" class="org.wh.spring.model.Order">
<constructor-arg index="0" type="java.lang.String" value="100110001110" />
<constructor-arg index="1" type="float" value="20.00" />
</bean>
</beans>
主入口,运行测试
ApplicationContextMain
package org.wh.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.wh.spring.model.User;
/**
* 主入口
*/
public class ApplicationContextMain {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
System.out.println(user);
((ClassPathXmlApplicationContext)context).close();
}
}
四、基于注解的bean初始化及应用
1.声明Bean注解:
-
@ Bean
指定为spring的bean
-
@Component
指定为组件,但无具体角色
-
@Controller
注册为控制器
-
@Service
注册为service,逻辑处理层对象
-
Repository
注册数据访问层对象
2.注入Bean注解
JSR是Java Specification Requests的缩写,意思是Java规范提案
-
@Autowired
由Spring提供
-
@Inject
由JSR-330提供
-
@Resource
由JSR-250提供
-
@PostConstruct
由JSR-250提供,在构造函数执行完之后执行,等价于xml配置中的bean的initMethod
-
@PreDestory
由JSR-250提供,在Bean销毁之前执行,等价于xml配置文件的bean的destroyMethod
3.配置类相关注解
-
@Configuration
声明当前类为配置类,相当于xml形式的Spring配置(类上)
-
@Bean
注解在方法上,声明当前方法的返回值为一个bean,替代xm中的方式(方法上)
-
@Value
为属性注入值(支持普通字符、系统属性、表达式结果、其他bean属性等)
-
@ComponentScan
用于对Component进行扫描,相当于xml中的(类上)
-
@WishlyConfiguration
为@Configuration与@ComponentScan的组合注解,可以替代这两个注解
3.示例演示
预览一下结构
User
package org.wh.spring.model;
public class User {
private String name;
private int age;
private Order order;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", order=" + order +
'}';
}
public void initMethod() {
System.out.println("-----------User类初始化方法--------------");
}
public void destroyMethod() {
System.out.println("-----------User类销毁方法--------------");
}
}
Order
package org.wh.spring.model;
public class Order {
private String orderNumber;
private float price;
public Order(String orderNumber, float price) {
this.orderNumber = orderNumber;
this.price = price;
}
public String getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
@Override
public String toString() {
return "Order{" +
"orderNumber='" + orderNumber + '\'' +
", price=" + price +
'}';
}
}
Product
package org.wh.spring.model;
import org.springframework.beans.factory.annotation.Value;
public class Product {
@Value("一本小黄书")
private String productName;
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
@Override
public String toString() {
return "Product{" +
"productName='" + productName + '\'' +
'}';
}
}
SpringApplicationConfig
package org.wh.spring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.wh.spring.model.Product;
@Configuration
public class SpringApplicationConfig {
@Bean("product")
public Product getProduct() {
return new Product();
}
}
UserService
package org.wh.spring.service;
import org.wh.spring.model.User;
public interface UserService {
User getUserInfo();
}
UserServiceImpl
package org.wh.spring.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.wh.spring.model.User;
import org.wh.spring.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private User user;
@Override
public User getUserInfo() {
return user;
}
}
UserController
package org.wh.spring.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.wh.spring.model.User;
import org.wh.spring.service.impl.UserServiceImpl;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Controller
public class UserController {
@Autowired
private UserServiceImpl userService;
public User getUser() {
return userService.getUserInfo();
}
@PostConstruct
public void initMethod() {
System.out.println("-----------UserController类初始化方法--------------");
}
@PreDestroy
public void destroyMethod() {
System.out.println("----------UserController类销毁方法--------------");
}
}
applicationContext.xml
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 用户 -->
<bean id="user" name="user" class="org.wh.spring.model.User" init-method="initMethod" destroy-method="destroyMethod" scope="singleton">
<property name="name" value="小明"></property>
<property name="age" value="6"></property>
<property name="order" ref="order"></property>
</bean>
<!-- 订单 -->
<bean id="order" name="order" class="org.wh.spring.model.Order">
<constructor-arg index="0" type="java.lang.String" value="100110001110" />
<constructor-arg index="1" type="float" value="20.00" />
</bean>
<context:component-scan base-package="org.wh.spring" ></context:component-scan>
</beans>
运行测试
package org.wh.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.wh.spring.controller.UserController;
import org.wh.spring.model.Product;
import org.wh.spring.model.User;
/**
* 主入口
*/
public class ApplicationContextMain {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取UserController
UserController userController = context.getBean(UserController.class);
User user = userController.getUser();
System.out.println(user);
// @Value
Product product = context.getBean(Product.class);
System.out.println(product);
// 关闭
((ClassPathXmlApplicationContext)context).close();
}
}
运行结果
-----------User类初始化方法--------------
-----------UserController类初始化方法--------------
User{name='小明', age=6, order=Order{orderNumber='100110001110', price=20.0}}
Product{productName='一本小黄书'}
----------UserController类销毁方法--------------
-----------User类销毁方法--------------