spring概述
spring可以做很多事情,它为企业级开发提供了丰富的功能。但是这些功能的底层都依赖于它的两个核心特性,控制反转(IOC)和面向切面(AOP)、
本篇文章主要介绍IOC。
现在 springboot 和spring cloud十分火爆,还是有必要看看两者之间的关系的
Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务,Spring Cloud是一个基于Spring Boot实现的云应用开发工具;Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;Spring Boot使用了约束优于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,Spring Cloud很大的一部分是基于Spring Boot来实现,Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。
Ioc基础
控制反转IOC是一种设计思想,DI(依赖注入)是实现IOC的一种方法。(下面的这张图画的太好了)
- 没有IOC的程序中我们使用面向对象编程对象的创建于对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制。
- 控制反转后将对象的创建转移给第三方。
IOC是spring框架的核心内容,使用多种方式完美的实现了IOC,可以使用xml配置,也可以使用注解,新版本的spring可以零配置实现IOC。
使用XML配置方式实现IOC
- 创建maven项目
- pom文件如下
<?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>com.kevin</groupId>
<artifactId>spring</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.3.0.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>4.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>
</dependencies>
</project>
使用无参构造方法创建对象
新建一个Music类
/**
* 音乐
*
* @author: kevin
* @Date: 2018/12/8
*/
public class Music {
public Music() {
System.out.println("播放周杰伦的《七里香》");
}
}
resources文件夹下新建music.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="jay" class="com.kevin.spring.demo1.entity.Music"></bean>
</beans>
测试类
package com.kevin.spring.demo1.test;
import com.kevin.spring.demo1.entity.Music;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author: kevin
* @Date: 2018/12/8
*/
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("music.xml");
Music jay = ctx.getBean("jay", Music.class);
}
}
运行结果
信息: Loading XML bean definitions from class path resource [music.xml]
播放周杰伦的《七里香》
使用有参构造方法创建对象
Person
package com.kevin.spring.demo2.entity;
/**
* 人类
*/
public abstract class Person {
public String name;
}
Student
package com.kevin.spring.demo2.entity;
/**
* 学生
*/
public class Student extends Person{
/**
* 身高
*/
public int height;
/**
* 有参构造函数
* @param name
* @param height
*/
public Student(String name,int height) {
this.name = name;
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"height=" + height +
", name='" + name + '\'' +
'}';
}
}
student.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="kevin" class="com.kevin.spring.demo2.entity.Student">
<constructor-arg name="name" value="kevin"></constructor-arg>
<constructor-arg name="height" value="170"></constructor-arg>
</bean>
<!--使用索引指定参数-->
<bean id="maomao" class="com.kevin.spring.demo2.entity.Student">
<constructor-arg index="0" value="maomao"></constructor-arg>
<constructor-arg index="1" value="100"></constructor-arg>
</bean>
</beans>
测试类
package com.kevin.spring.demo2.test;
import com.kevin.spring.demo2.entity.Person;
import com.kevin.spring.demo2.entity.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("student.xml");
Person kevin = ctx.getBean("kevin", Student.class);
Person maomao = ctx.getBean("maomao", Student.class);
System.out.println(maomao);
System.out.println(kevin);
}
}
输出
信息: Loading XML bean definitions from class path resource [student.xml]
Student{height=100, name='maomao'}
Student{height=170, name='kevin'}
通过属性赋值
Animal
package com.kevin.spring.demo3.entity;
/**
* 动物
*/
public class Animal {
/**
* 动物名称
*/
private String name;
public Animal() {
}
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
'}';
}
}
animal.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.kevin.spring.demo3.entity.Animal">
<property name="name" value="dog"></property>
</bean>
<bean id="cat" class="com.kevin.spring.demo3.entity.Animal" p:name="cat"></bean>
</beans>
测试
package com.kevin.spring.demo3.test;
import com.kevin.spring.demo3.entity.Animal;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("animal.xml");
Animal dog = ctx.getBean("dog",Animal.class);
Animal cat = ctx.getBean("cat",Animal.class);
System.out.println(cat);
System.out.println(dog);
}
}
输出结果
信息: Loading XML bean definitions from class path resource [animal.xml]
Animal{name='cat'}
Animal{name='dog'}
对象引用
Tyre
package com.kevin.spring.demo4.entity;
/**
* 轮胎
* @author: kevin
* @Date: 2018/12/8
*/
public class Tyre {
private String name;
public Tyre(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Tyre{" +
"name='" + name + '\'' +
'}';
}
}
Car
package com.kevin.spring.demo4.entity;
/**
* 车
*/
public class Car {
private String name;
private Tyre tyre;
public Car(String name, Tyre tyre) {
this.name = name;
this.tyre = tyre;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Tyre getTyre() {
return tyre;
}
public void setTyre(Tyre tyre) {
this.tyre = tyre;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", tyre=" + tyre +
'}';
}
}
测试
package com.kevin.spring.demo4.test;
import com.kevin.spring.demo4.entity.Car;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("car.xml");
Car bike = ctx.getBean("bike", Car.class);
System.out.println(bike);
}
}
输出结果
信息: Loading XML bean definitions from class path resource [car.xml]
Car{name='bike', tyre=Tyre{name='自行车轮胎'}}
对象作用域
Spring定义了多种作用域,可以基于这些作用域创建bean,包括:
1、spring中默认是单例的,我们通过之前的代码演示下
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.kevin.spring.demo3.entity.Animal">
<property name="name" value="dog"></property>
</bean>
<bean id="cat" class="com.kevin.spring.demo3.entity.Animal" p:name="cat"></bean>
</beans>
测试
package com.kevin.spring.demo3.test;
import com.kevin.spring.demo3.entity.Animal;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试类
*/
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("animal.xml");
Animal dog1 = ctx.getBean("dog",Animal.class);
Animal dog2 = ctx.getBean("dog",Animal.class);
System.out.println(dog1 == dog2);
}
}
输出结果
true
这样验证了从容器中取回的对象默认是单例的。
2、设置成Prototype
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.kevin.spring.demo3.entity.Animal" scope="prototype">
<property name="name" value="dog"></property>
</bean>
<bean id="cat" class="com.kevin.spring.demo3.entity.Animal" p:name="cat"></bean>
</beans>
测试
ApplicationContext ctx = new ClassPathXmlApplicationContext("animal.xml");
Animal dog1 = ctx.getBean("dog",Animal.class);
Animal dog2 = ctx.getBean("dog",Animal.class);
System.out.println(dog1 == dog2);
输出结果
false
延迟初始化bean
ApplicationContext实现的默认行为是在启动时将所有的singleton bean 提前进行实例化。这样配置中或者运行环境的错误就会立刻发现。如果你想延迟初始化。可以在xml中进行配置
<bean id="kevin" class="com.kevin.spring.demo2.entity.Student" lazy-init="true">
<constructor-arg name="name" value="kevin"></constructor-arg>
<constructor-arg name="height" value="170"></constructor-arg>
</bean>
测试
public static void main(String[] args) throws InterruptedException {
ApplicationContext ctx = new ClassPathXmlApplicationContext("student.xml");
Thread.sleep(3000);
Person kevin = ctx.getBean("kevin", Student.class);
System.out.println(kevin);
}
大家自己运行后发现,确实并不是启动后就加载的。
回调方法
Student
public void init() {
System.out.println("执行init方法");
}
public void over() {
System.out.println("执行over方法");
}
student.xml
<bean id="kevin" class="com.kevin.spring.demo2.entity.Student" lazy-init="true" init-method="init" destroy-method="over">
<constructor-arg name="name" value="kevin"></constructor-arg>
<constructor-arg name="height" value="170"></constructor-arg>
</bean>
测试方法
public static void main(String[] args) throws InterruptedException {
ApplicationContext ctx = new ClassPathXmlApplicationContext("student.xml");
Thread.sleep(3000);
Person kevin = ctx.getBean("kevin", Student.class);
System.out.println(kevin);
}
输出结果
Student 初始化
执行init方法
Student{height=170, name='kevin'}
本篇文章暂时先介绍到这里,天气真的很冷,没有暖气,冻死我的手了。好了,玩的开心!
完整代码:https://github.com/runzhenghengbin/spring-study/tree/master/spring-demo01
参考:https://www.cnblogs.com/best/p/5727935.html