Spring的学习二(Spring Ioc和DI,AOP简介)
Posted lixiang-nq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring的学习二(Spring Ioc和DI,AOP简介)相关的知识,希望对你有一定的参考价值。
一:Spring Ioc,DI,AOP简介
-
IOC控制反转:将原本在程序中手动创建对象的控制权,交由Spring框架来管理
原理:
- 读取标注或者配置文件,看看Shoe依赖的是哪个Source,拿到类名
- 使用反射的API,基于类名实例化对应的对象实例
- 将对象实例,通过构造函数或者 setter,传递给 ShoeShop
- 以前是我们自己new对象(自己买材料,工具自己做鞋子),现在只要告诉IOC这个容器(鞋店),他自动给你new好,你直接取对象就好了,省去了我们自己new对象的过程
-
-
DI:依赖注入:指 Spring 创建对象的过程中,将对象依赖属性(简单值,集合,对象)通过配置设值给该对象
-
AOP:面向切面编程
- 首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。
- 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务
- 所谓的周边功能,比如性能统计,日志,事务管理等等
- 周边功能在 Spring 的面向切面编程AOP思想里,即被定义为切面
- 在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP
-
DI注入两种方法:基于xml方式和基于注解方式
- 基于xml方式(有三种方法)
- set注入
- 构造器注入
- p命名空间注入
(1)基于set方式注入(注意,这个原理是我们类中的set方法,也就是说我们必须在那个类中写set方法,你可以试一下,将set方法删除,这将会报错)首先在src目录下新建xml文件,取名为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 http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
以上为自动生成的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方法删除,这将会报错)
<bean id="shoe" class="com.blog.entity.Shoe"><!--这就相当于我们 Shoe show=new Shoe()--> <property name="name" value="安踏"></property><!--鞋子牌子 赋值--> <property name="price" value="300"></property><!--鞋子价格 赋值--> <property name="size" value="40"></property><!--鞋子尺码 赋值--> </bean>
这段代码就把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中配置如下
<bean id="shoe" class="com.blog.entity.Shoe"><!--这就相当于我们 Shoe show=new Shoe()--> <property name="name" value="安踏"></property><!--鞋子牌子--> <property name="price" value="300"></property><!--鞋子价格--> <property name="size" value="40"></property><!--鞋子尺码--> </bean> <!--=====上是set=================宇宙无敌分界线=======下是构造器==================--> <bean id="shoe1" class="com.blog.entity.Shoe"> <constructor-arg name="name" value="安踏"></constructor-arg><!--鞋子牌子--> <constructor-arg name="price" value="300"></constructor-arg><!--鞋子价格--> <constructor-arg name="size" value="40"></constructor-arg><!--鞋子尺码--> </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
<bean id="shoe" class="com.blog.entity.Shoe"><!--这就相当于我们 Shoe show=new Shoe()--> <property name="name" value="安踏"></property><!--鞋子牌子--> <property name="price" value="300"></property><!--鞋子价格--> <property name="size" value="40"></property><!--鞋子尺码--> </bean> <!--======================宇宙无敌分界线=========================--> <bean id="shoeshop" class="com.blog.service.ShoeShop"> <property name="id" value="1001"></property> <property name="name" value="安踏旗舰店"></property> <property name="shoe" ref="shoe"></property>//只改这里,没错,引用类型只要将valueg改为ref即可,ref的属性为其他对应的bean的id值,比如我这里有shop内需要一个shoe的对象,我们找到前面有一个bean的class为xxx.shoe,其id为shoe </bean>
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简介)的主要内容,如果未能解决你的问题,请参考以下文章