一:Spring Ioc,DI,AOP简介
-
IOC控制反转:将原本在程序中手动创建对象的控制权,交由Spring框架来管理
原理:
- 读取标注或者配置文件,看看Shoe依赖的是哪个Source,拿到类名
- 使用反射的API,基于类名实例化对应的对象实例
- 将对象实例,通过构造函数或者 setter,传递给 ShoeShop
- 以前是我们自己new对象(自己买材料,工具自己做鞋子),现在只要告诉IOC这个容器(鞋店),他自动给你new好,你直接取对象就好了,省去了我们自己new对象的过程
-
-
DI:依赖注入:指 Spring 创建对象的过程中,将对象依赖属性(简单值,集合,对象)通过配置设值给该对象
-
AOP:面向切面编程
- 首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。
- 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务
- 所谓的周边功能,比如性能统计,日志,事务管理等等
- 周边功能在 Spring 的面向切面编程AOP思想里,即被定义为切面
- 在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP
- 基于xml方式(有三种方法)
- set注入
- 构造器注入
- p命名空间注入
(1)基于set方式注入(注意,这个原理是我们类中的set方法,也就是说我们必须在那个类中写set方法,你可以试一下,将set方法删除,这将会报错)首先在src目录下新建xml文件,取名为applicationContext.xml
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">
以上为自动生成的applicationContext.xml的代码,这里将是我们配置Spring的地方,我们将相应的包建好,在entity包中建好Shoe.java代码如下(注意,这个原理是我们类中的set方法,也就是说我们必须在那个类中写set方法,你可以试一下,将set方法删除,这将会报错)
package com.blog.entity;
public class Shoe {
private int size;//尺码
private String name;//鞋子名字
private int price;//鞋子价格
//重写tostring方法
@Override
public String toString() {
return this.name+":"+this.size+":"+this.price;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
我们怎么将我们Shoe这个类放到IOC中,让IOC这个容器给我们初始化好呢?在applicationContext.xml中加入下面这段代码(注意,这个原理是我们类中的set方法,也就是说我们必须在那个类中写set方法,你可以试一下,将set方法删除,这将会报错)
这段代码就把Shoe这个类放到了IOC容器中了,那么怎么从里面拿呢?我们新建一个Test类用来测试
//拿到了context上下文对象,我们通过这个对象去获取IOC中的bean
ApplicationContext cOntext=new ClassPathXmlApplicationContext("applicationContext.xml");//这个参数就是我xml的位置
Shoe shoe=(Shoe)context.getBean("shoe");//这个参数是我们在bean里面的id值,通过这个,我们去IOC里找id为shoe,返回一个Object,用Shoe接受
System.out.println(shoe);//通过之前的tostring方法,打印Shoe
我们可以看到,我们拿到了Shoe这个对象及其属性(注意,这个原理是我们类中的set方法,也就是说我们必须在那个类中写set方法,你可以试一下,将set方法删除,这将会报错)
(2)基于构造器方式注入(注意,这个原理是我们类中的构造器,也就是说我们必须在那个类中写有参数的构造器,你可以试一下,将有的参数构造器删除,这将会报错)
在applicationContext.xml中新加bean,在bean中配置如下
test中代码和set方式注入一样,最终结果如下
2.基于注解方式
这时候我们就不用去配置xml文件了,Shoe.java文件和上面一样,在类前加上 @Component 在属性前加@Value("值")
测试类中:之前的代码也都注释掉,因为我们获取bean的方法变了,(因为我们都没有去配置xml了)
package com.blog.test;
import com.blog.entity.Shoe;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestShoe {
public static void main(String[] args){
//拿到了context上下文对象,我们通过这个对象去获取IOC中的bean
// ApplicationContext cOntext=new ClassPathXmlApplicationContext("applicationContext.xml");//这个参数就是我xml的位置
// Shoe shoe=(Shoe)context.getBean("shoe");//这个参数是我们在bean里面的id值,通过这个,我们去IOC里找id为shoe,返回一个Object,用Shoe接受
// System.out.println(shoe);
ApplicationContext cOntext=new AnnotationConfigApplicationContext(Shoe.class);//通过Shoe.class,反射拿到Shoe所在的包和类名
Shoe shoe=(Shoe)context.getBean("shoe");
System.out.println(shoe);
}
}
结果如下
当然,现在我们都是基本类型的注入,还有List Array Map 等等集合的注入,大家可以去百度怎么去注入,接下来还有一个引用类型的注入,我新建一个包,在包内新建shoeShop;(为了说明注解的其他配置项不在同一个包需要在xml文件配置扫描器 )
<context:component-scan base-package="com.blog.service">context:component-scan>
set方法1配置引用类型:用ref
//只改这里,没错,引用类型只要将valueg改为ref即可,ref的属性为其他对应的bean的id值,比如我这里有shop内需要一个shoe的对象,我们找到前面有一个bean的class为xxx.shoe,其id为shoe
set方法2配置引用类型:用autowire="byName/byType/constructor"=====通过id//通过类型//通过构造器===========》自动装入,也就是IOC会根据我们的byName去找bean是否有id为shoe的//是否有类型为Shoede//是否构造器的参数一致的(也可以在头信息中一次性将所有的bean统一设置为自动装配 default-autowire="byName")
注解方法配:置引用类型(未完)2019年3月9日22:18:41
Spring的学习二(Spring Ioc和DI,AOP简介)