Spring笔记2(IOC容器)

Spring(笔记2)

IOC容器

1、IOC的概念跟原理

a. 概念:

控制反转,把对象的创建与对象之间的调用交给spring管理,使用IOC目的是为了降低耦合度

b. IOC底层原理
Xml解析,工厂模式,反射

原始方式 new 耦合度太高
工厂模式解耦合(非最终方案):
创建一个工厂类,添加方法返回所需要的对象(工厂方法中去new对象)

在这里插入图片描述
在这里插入图片描述

IOC解耦过程:
在这里插入图片描述

IOC解耦是将耦合度降到最低限度

2、IOC接口

a. IOC思想是基于IOC容器去完成的,IOC容器底层就是对象的工厂
b. 要对工厂进行实例化,Spring提供了IOC的两种实现方式:

BeanFactory
ApplicationContext
相同点:

他们都能实现加载配置文件,通过工厂过程去创建对象

不同点:
BeanFactory是spring的内部使用接口,一般不提供给开发人员使用,加载配置文件时不会创建对象,获取对象或使用对象时才会创建对象
ApplicationContext是BeanFactory的子接口,一般开发人员使用,加载配置文件时就会将配置文件中的对象创建

C.实现类

ApplicationContext:

ClassPathXmlApplicationContext:编译后的路径(src下的路径)
FileSystemXmlApplicationContex:对应的是盘全路径(E:\MyEclipse_WordSpace\FirstSpring\src)

BeanFactory:ApplicationContext

3、IOC操作(bean管理操作)

a.bean管理:

spring创建对象
spring注入属性

b.bean管理有两种方式:

基于xml配置方式
基于注解方式

4、IOC操作bean管理(基于xml方式)

a.基于xml创建对象
在这里插入图片描述

id:给对象取一个唯一标识(不是创建对象的名字)
class:创建类的全路径(包类的路径)
name:作用与id相同,(id不能加特殊符号,name可以加特殊符号)

b.基于xml方式注入属性(注入属性要在创建对象的基础上进行)

DI:依赖注入,注入属性(DI是IOC的一种具体实现)

c.第一种注入方式:set方法注入
创建类,定义属性和对应的set方法
在配置文件中配置bean,并且配置属性

在这里插入图片描述d.第二种注入方式:有参构造注入
创建类、属性、有参构造
在spring配置文件中进行配置

在这里插入图片描述
e. p名称空间(了解)
添加p名称空间约束

xmlns:p=http://www.springframework.org/schema/p

进行属性注入
在这里插入图片描述

5.IOC操作bean管理(xml注入其他类属性)

a.字面量(向一个类中设置属性固定值)(创建属性时直接赋值、标签赋值)

赋值null值

在这里插入图片描述设置属性值中包含特殊符号<>:把带特殊符号的内容写到CDATA中

在这里插入图片描述b.注入属性——外部bean
Service中调用dao

//创建PersonDao类型属性。生成set方法
private PersonDao personDao;
public void setPersonDao(PersonDao personDao) {
	this.personDao = personDao;
}

在这里插入图片描述
c.注入属性——内部bean
一对多关系:部门与员工(一个部门有多个员工,每个员工都有所属部门)
在实体类中表示一对多关系
在spring配置文件中进行配置
在这里插入图片描述
d.注入属性——级联赋值
第一种写法:
在这里插入图片描述第二种写法:
在这里插入图片描述

6、IOC操作bean管理-xml注入集合属性

1) 创建类,定义数组、list、map、set类型的属性,并生成set()
2) 在spring配置文件中配置
3) 在集合中设置对象属性值

<!-- 注入集合类型属性 -->
<bean id="stu2" class="com.spring.domain.Student1">
	<!-- 数组类型属性注入 -->
	<property name="courses">
		<list>
			<value>语文</value>
			<value>数学</value>
			<value>英语</value>
		</list>
	</property>
	<!-- list集合属性注入 -->
	<property name="lists">
		<list>
			<value>aaaa</value>
			<value>bbbb</value>
			<value>cccc</value>
		</list>
	</property>
	<!-- map集合属性注入 -->
	<property name="maps">
		<map>
			<entry key="k1" value="value1"></entry>
			<entry key="k2" value="value2"></entry>
		</map>
	</property>
	<!-- set集合属性注入 -->
	<property name="sets">
		<set>
			<value>s1</value>
			<value>s2</value>
			<value>s3</value>
		</set>
	</property>
	
	<!-- list对象集合属性注入 -->
	<property name="courseList">
		<list>
			<ref bean="course1"/>
			<ref bean="course2"/>
		</list>
	</property>
</bean>

<bean id="course1" class="com.spring.domain.Course">
<property name="cname" value="java"></property>
<property name="time" value="6"></property>
<property name="teacher" ref="teacher1"></property>
</bean>

<bean id="course2" class="com.spring.domain.Course">
<property name="cname" value="mysql"></property>
<property name="time" value="7"></property>
<property name="teacher" ref="teacher1"></property>
</bean>

4) 把集合注入的部门提取出来

a. 在spring配置文件中引入名称空间util

xmlns:util=http://www.springframework.org/schema/util
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util.xsd
"

b) 使用util标签完成list集合注入提取

<bean id="stu3" class="com.spring.domain.Student2">
	<property name="lists" ref="list1"></property>
</bean>
<util:list id="list1">
	<value>aaaa</value>
	<value>bbbb</value>
	<value>cccc</value>
</util:list>

7、IOC操作bean管理-FactoryBean

1). spring中有两种bean,一种普通的bean(我们自己建的bean),还有工厂bean(FactoryBean)
2). 普通bean(定义什么类型,返回什么类型)
在spring配置文件中定义的bean类型就是返回类型
3). 工厂bean:在spring中配置类型可以和返回类型不一样

a.创建类,让这个类作为工厂bean,实现FactoryBean接口

public class MyBean implements FactoryBean<Student1> {
//定义返回的bean
public Student1 getObject() throws Exception {
	List<String> list = new ArrayList<String>();
	list.add("1111");
	list.add("2222");
	list.add("333");
	
	//设置MyBean返回对象是stu1
	Student1 stu = new Student1();
	stu.setLists(list);
	return stu;
}

public Class<?> getObjectType() {
	// TODO Auto-generated method stub
	return null;
}

public boolean isSingleton() {
	// TODO Auto-generated method stub
	return false;
}
}

<bean id="stu3" class="com.spring.factorybean.MyBean"></bean>

8、IOC操作bean管理-bean的作用域

1). Spring配置文件bean标签创建bean可以是一个单实例,也可以是一个多实例,默认单例(单实例每次只有一个对象,多实例每次都创建一个新的对象),Spring中可以去配置单实例还是多实例
2). 设置单例还是多例
scope属性设置

singleton  单实例(默认)
prototype  多实例
request、session

3). singleton和prototype 区别
a.一个实例,一个是多实例
b.设置为singleton时,加载配置文件时就会创建单实例对象,设置为prototype时,在调用getBean方法时创建多实例对象

9、IOC操作bean管理-bean生命周期

1)从对象创建到销毁的过程
2)bean生命周期

	a.第一步,通过构造器创建bean实例
	b.第二步,为bean属性设置值和对其他bean的引用
	c.第三步,调用bean的初始化方法(需要进行配置)
	d.第四步,bean使用
	e.第五步,调用bean的销毁方法(需要进行配置)

3)演示bean生命周期
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述

4)生命周期补充

Bean的后置处理器
初始化前:把bean实例传递给bean后置处理器的方法
初始化后:把bean实例传递给bean后置处理器的方法、

5) 演示添加后置处理器

a.	创建类,实现BeanPostProcessor接口
b.	配置后置处理器 

在这里插入图片描述

public class MyBeanPost implements BeanPostProcessor {

//初始化之后
	public Object postProcessAfterInitialization(Object bean, String arg1)
		throws BeansException {
		System.out.println("初始化之后执行");
		return bean;
	}

//初始化之前
	public Object postProcessBeforeInitialization(Object bean, String arg1)
		throws BeansException {
		System.out.println("初始化之前执行");
		return bean;
	}
}

	<!-- 配置后置处理器 -->
<bean id="myBeanPost" class="com.spring.processor.MyBeanPost"></bean>

10、IOC-操作bean-xml自动装配

1)自动装配

这种是手动装配置
自动装配:根据指定装配规则(属性名称,或者是属性类型),spring自动将匹配的属性值进行注入(不需要标签注入)

2)演示自动装配

原始方式:

<bean id="emp" class="com.spring.autowire.Emp">
	<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.spring.autowire.Dept"></bean>

自动装配:

byName:根据属性名称去装配,注入值bean的id值要和类属性名称一致
<bean id="emp" class="com.spring.autowire.Emp" autowire="byName"></bean>
<bean id="dept1" class="com.spring.autowire.Dept"></bean>

byType:根据属性类型装配,注入bean的类型要和类属性类型一致
<bean id="emp" class="com.spring.autowire.Emp" autowire="byType"></bean>
<bean id="dept1" class="com.spring.autowire.Dept"></bean>

注:byType中有两个Dept类的bean,spring根据类型找到了两个bean,无法确认要注入哪个bean,会报错,相同类型的bean只能定义一个

11、IOC-操作bean管理-基于注解方式

1)注解:
a.注解是代码里的一种特殊标记,
格式:
@注解名称(属性名=属性值)
@注解名称(属性名1=属性值1,属性名2=属性值2)
@注解名称
单元测试@Test注解
b.注解的作用范围:注解可以作用在类上面、方法上、属性上
c.注解的目的:简化xml配置

2)有哪些注解
Spring针对bean管理中创建对象提供以下注解:

@Component(普通对象)
@Service(业务逻辑层或service层)
@Controller(web层)
@Reponsitory(dao层或者持久层)

上面四个注解功能是一样的,都可以创建对象

3)基于注解方式创建对象
a)导入依赖 aop.jar
b)开启组件扫描
告诉spring要在哪个类上加注解,让spring扫描哪个类

引入context名称空间
<context:component-scan base-package=“com.spring.*”></context:component-scan>

base-package:告诉spring要扫描的包,多个包用逗号隔开
b) 创建类,添加创建对象的注解

@Component(value="userService")
public class UserService {
public void add() {
	System.out.println();
	}
}

此处的value就等价于xml配置bean标签的id,也就是创建对象的标识

Value属性值可以不写,如果不写默认类名称首字母小写

@Component//<bean id="userService" class="">
public class UserService {
public void add() {
	System.out.println();
	}
}

4)开启组件扫描其他

<!-- use-default-filters不写,spring例有一个默认的filter去找到包中所有类去扫码  -->
<!-- use-default-filters="false":不使用默认filter,使用自己配置的filter -->
<context:component-scan base-package="com.spring.*" use-default-filters="false">
	<!-- context:include-filter:设置扫描哪些内容 -->
	<!-- 到base-package包中只扫描带@Controller的注解-->
	<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>


<context:component-scan base-package="com.spring.*">
	<!-- 设置哪些内容不进行扫描@Controller -->
	<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

5)基于注解实现属性注入
针对对象类型:

@AutoWired 根据属性类型自动注入
@Qualifier 根据属性名称注入
@Resource  既可以根据类型注入,也可以根据属性注入

针对普通类型:

@Value  注入是一个普通类型

a.@AutoWired(属性类型) ,找到要注入的属性接口的实现类注入
创建service和dao对象;
在service中注入dao对象,在service类中添加dao类型的属性,不要添加set方法

@Component
public class UserService {

//根据属性类型注入
@Autowired
private UserDao userDao;

public void add() {
	System.out.println("service");
	userDao.update();
	}
}

public interface UserDao {
public void update();
}

@Repository
public class UserDaoImpl implements UserDao {

public void update() {
	System.out.println("update");
	}
}

b.@Qualifier根据属性名称注入
当一个接口有多个实现类,spring不知道要注入哪个实现类
与@Autowird一起使用

@Autowired
@Qualifier(value="userDaoImpl")
private UserDao userDao;

c)@Resource既可以感觉类型注入,也可以根据名称注入

@Resource//根据类型
@Resource(name="userDaoImpl")//根据属性名称注入
private UserDao userDao;

d.@Value

@Value(value="zhangsan")
private String name ;

6) 完全注解开发(springboot)
a. 创建配置类,替代xml配置文件

//作为配置类
@Configuration
//代表开启组件扫描
@ComponentScan(basePackages={"com.spring.*"})
public class SpringConfig {

}

b. 编写测试类

 @Test
public void testAutowire(){
	//加载配置类
	ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
	//获取创建对象
	UserService service = context.getBean("userService",UserService.class);
	service.add();
}

7)注解配置bean作用域

@Scope(value="singleton")
Singleton:配置单例
Prototype:配置多例
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值