Spring IOC

Spring IOC

1.1 概述
控制反转是一个比较抽象的概念,对于初学者不好理解,我们举例说明。在实际生活中,人们要用到一样东西时,人们的基本想法是找到东西,比如想喝杯橙汁,在没有饮品店的日子里,最直观的做法是,要买果汁机、橙子,准备开水。请注意这是你自己" 主动"创造的过程,也就是一杯橙汁需要主动创造。然而到了今时今日,由于饮品店的盛行, 已经没有必要自己去榨橙汁了。想喝橙汁的想法一出现,第一个想法是找到饮品店的联系方式,通过电话、微信等渠道描述你的需要、地址、联系方式等,下订单等待,过会就会有人送上橙汁了。请注意你并没有"主动"创造橙汁,也就是橙汁是由饮品店创造的,而不是你,但是也完全达到了你的要求。
1.2 控制反转
控制反转是一种通过描述(在Java中可以是xml或注解)并通过第三方去产生或者获取对象的方式
SpringIOC容器的设计主要是基于BeanFactoryAppilicationContext两个接口
BeanFactory是Spring定义的最底层的接口,AppilicationContextBeanFactory的子接口之一
BeanFactory中定义了多个抽象方法
getBean 用于获取配置给SpringIOC容器的bean
isSingle
isPrototype
getAliases 获取别名
ApplicationContext的间接实现类ClassPathXmlApplicationContext

spring-config.xml:

<beans >
<bean id="userDaoImpl" class="dao.impl.UserDaoImpl"></bean>
<bean id="userBizImpl" class="biz.impl.UserBizImpl" scope="singleton">
		<property name="bName" value="bName1"></property>
		<property name="bNum" value="1"></property>
		<property name="userDao" ref="userDaoImpl"></property>(注入自定义类)
</bean>
</beans>

这里定义了两个bean,这样SpringIOC容器在初始化的时候就能找到他们,然后使用ClassPathXmlApplicationContext就可以将其初始化

ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"spring-config.xml "});
UserBiz userBiz  =  (UserBiz) ac.getBean("userBizImpl");

Spring bean要先初始化,才会进行依赖注入
初始化的3个步骤:
(1) resource定位,通过xml或者注解的方式定位
(2) beandefinition的载入,spring通过配置获取pojo(用于生成实例)
(3) beandefinition的注册,把载入的pojo往springIOC容器中注册
这样就可以得到springIOC容器的bean了

1.3 setter注入
spring-config.xml文件

<beans >
<bean id="userDaoImpl" class="dao.impl.UserDaoImpl"></bean>
<bean id="userBizImpl" class="biz.impl.UserBizImpl" scope="singleton">
		<property name="bName" value="bName1"></property>
		<property name="bNum" value="1"></property>
		<property name="userDao" ref="userDaoImpl"></property>(注入自定义类)
</bean>
</beans>

注意:配bean时候,若没有写id,则spring将会采用“全限定名#{number}”的格式生成编号,如:
biz.impl.UserBizImpl #1、biz.impl.UserBizImpl#2

userBizImpl.java文件

private String bName;
private int bNum;
private UserDao userDao;
/*** getter setter  ***/

Test.java文件

ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"spring-config.xml "});
UserBiz userBiz  =  (UserBiz) ac.getBean("userBizImpl");

注意:
scope属性表示bean的作用域 不写默认是单例模式singleton,每次实例化bean都是同一个bean
prototype多例 每次实例化bean都是新的,
request 每次请求时实例化bean是新的
session 浏览器打开关闭之间实例化bean是新的
global session 相当于 application 服务器打开关闭之间实例化bean是新的

1.4 通过构造注入
application.xml文件

<bean id="userDaoImpl" class="dao.impl.UserDaoImpl"></bean>
<bean id="userBizImpl3" class="biz.impl.UserBizImpl" scope="singleton">
		<constructor-arg index="0" value="bName3"></constructor-arg>
		<constructor-arg index="1" value="3"></constructor-arg>
		<constructor-arg index="2" ref="userDaoImpl"></constructor-arg>
</bean>

userBizImpl.java文件,需要有对应的构造器

//需要有对应的构造器
public UserBizImpl(String bName, int bNum,UserDao userDao) {
		super();
		this.bName = bName;
		this.bNum = bNum;
		this.userDao = userDao;
}

1.5 工厂方法注入(静态工厂、非静态工厂)

1.6 注入集合

<bean id="people6" class="entity.People">
		<property name="id" value="1"></property>
		<property name="name" value="张三"></property>
		<property name="hobbies">  类那边 需 new一个 ArrayList
			<list>
				<value>唱歌</value>
				<value>跳舞</value>
			</list>
		</property>
		<property name="loves">		类那边 需 new一个 HashSet
			<set>
				<value>唱歌2</value>
				<value>跳舞2</value>
			</set>
		</property>
		<property name="works">		类那边 需 new一个 HashMap
			<map>
				<entry>
					<key><value>上午</value></key>
					<value>写代码</value>
				</entry>
				<entry>
					<key><value>下午</value></key>
					<value>测试代码</value>
				</entry>
			</map>
		</property>
		<property name="addresses">		类那边 需 new一个 Properties
			<props>
				<prop key="address1">aaaaa</prop>
				<prop key="address2">bbbbb</prop>
			</props>
		</property>
	</bean>

1.7 通过注解装配bean

1.7.1 @Component

Role.java文件

@Component(value="role")
public class Role {

	@Value("123")//这里 id是long型 spring注入时候会为其转型
	private Long id;
	
	@Value("role_name_1")
	private String roleName;
	
	@Value("note1")
	private String note;

注意:

@Component(value="role")//相当于xml方式定义bean中的id 不写@Component 默认为类名并且首字母小写

PojoConfig.java文件

@Configuration
@ComponentScan
public class PojoConfig {

}

Test.java文件

ApplicationContext ac = new AnnotationConfigApplicationContext(PojoConfig.class);
Role role = (Role) ac.getBean("role");//也可以这么获取Role role = ac.getBean(Role.class);
System.out.println(role.getId());
打印结果 123

注意:

@ComponentScan只会扫描所在包的Java类,若需要指定哪些类则需
@ComponentScan(basePackageClasses = {Role.class,User.class} )
或者
@ComponentScan(basePackages = {"entity.Role","biz.impl"})

1.7.2 @Autowired

@Autowired
private Role role;

也可以在setter方法上注解

@Autowired
public void setRole(Role role) {
	this.role = role;
}

注意:

@Autowired默认情况下,spring会认为一定要找到对应的bean注入这个字段,否则报错,但有时候可有可无,则需
@Autowired(required = false)

1.7.3 @Primary和@Qualifier

当下面这个UserDao有多个实现类的时候,spring就不知道该注入哪个实现类了就会报错
@Autowired
private UserDao userDao;

那么需要这么解决,表示优先注入这个实现类

@Primary
public class UserDaoImpl2 implements UserDao{

}

或者

@Autowired
@Qualifier("userDaoImpl2")
private UserDao  userDao;

在构造中使用@Autowired
public UserBizImpl(@Autowired UserDao userDao) {
this.userDao = userDao;
}(编译过不去,原因未明)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值