Spring之Ioc

认识Spring

  1. Spring 是面向java的开源框架,由20多个模块组成。核心技术是Ioc和AOP
  2. Spring 作为一个容器,负责管理,存储java对象
  3. Spring 作用:主要是解决对象,模块之间的耦合关系,降低代码耦合度,实现解耦
  4. Spring 优点:
    • 轻量
      jar包小,一般小于1M,不占用资源,运行效率高
    • 针对接口编程,实现解耦合
      通过Ioc控制反转,管理对象,由容器负责生成对象,解决对象间的依赖关系,实现解耦合
    • AOP编程支持
      AOP表示面向切面的编程方式,解决了繁杂的事务管理代码的实现,通过声明的方式管理事务,提高开发效率
    • 方便集成各种优秀的框架
      Spring 不排斥各种优秀的框架,可以轻易的与各种框架组合在一起

附: Spring 官网

Spring核心技术之Ioc

理解Ioc

Ioc也叫控制反转,可以理解为是一种指导编程的思想。它的主要功能是使用Spring容器实现对象的创建,属性赋值,对象间的关系管理(实现解耦合)。
控制:是对对象的创建,属性赋值,对象关系管理。控制对象从创建到销毁的全生命周期。
反转:如果将一般情况下开发者负责创建对象(new),属性赋值,对象关系管理为正转,那么反转就是由Spring容器进行这一系列操作。

接触过的Ioc容器:Tomcat容器

tomcat就是一个ioc的实现容器, tomcat可以创建servlet, listener,filter
tomcat创建servlet对象, 过滤器对象等,并把这些对象放在tomcat的内部(map)保存。
tomcat也叫做jsp/servlet容器,可以在程序代码之外创建servlet对象。

使用Ioc小案例

注意:这里需要使用spring-context依赖

  1. 定义接口UserDao和接口实现类UserDaoImpl
//Dao层
public Interface UserDao{
	void doSome();
}
//dao层接口实现类
@Override
public class UserDaoImpl implements UserDao{
	public void doSome(){
		System.out.println("------doSome执行了------")
	}
}
  1. 创建Spring配置文件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">
       <!-- 这里的bean相当于 UserDaoImpl userdao = new UserDaoImpl() -->
	<bean id="userDao" class="com.dao.UserDaoImpl" />
</beans>
  1. 编写测试类MyTest
public class MyTest{
	@Test
	public void testInsertUser(){
		//将bean装配到ApplicationContext对象中
		ApplicationContext ctx = new ClassPathXMLApplicationContext("applicationContext.xml");
		//通过匹配bean的id来获取对象
		UserDaoImpl impl = (UserDaoImpl)ctx.getBean("userDao");
		impl.doSomme();
	}
}

ApplicationContext接口有两个实现类:

  1. ClassPathXMLApplicationContext :applicationContext.xml在项目类路径下
  2. FileSystemXMLApplicationContext:applicationContext.xml在项目根路径下

bean的装配

  1. <bean id =“user” class="User类的全限定名称’ />
    可以理解为:User user = new User();默认通过无参构造方法创建对象
  2. bean的作用域:scope属性
    1. singleton 单例模式:叫这个名称的对象只有一个实例
    2. prototype 原型模式:即每次使用 getBean 方法获取的同一个的实例都是一个新的实例。
    3. )request : 对于每次 HTTP 请求,都将会产生一个不同的 Bean 实例
    4. )session : 对于每个不同的 HTTP session,都将产生一个不同的 Bean 实例
      注意:
      (1)对于 scope 的值 request、session 只有在 Web 应用中使用 Spring 时,该作用域才有效。
      (2)对于 scope 为 singleton 的单例模式,该 Bean 是在容器被创建时即被装配好了。
      (3)对于 scope 为 prototype 的原型模式,Bean 实例是在代码中使用该 Bean 实例时才进行装配的。
//单例模式
public class MyTest{
	@Test
	public void testInsertUser(){
		//执行完这条语句后,就会将配置文件中的所有bean都扫描一遍,将都有的bean进行加载,所有bean的对象通过这句创建
		ApplicationContext ctx = new ClassPathXMLApplicationContext("applicationContext.xml的路径");
	    //获取不同的id来获取对象
		User user = (User)ctx.getBean("user");
	}
}
//原型模式
public class MyTest{
	@Test
	public void testInsertUser(){
		//执行完这条语句后,就会将配置文件中的所有bean都扫描一遍,将都有的bean进行加载,但不会创建对象
		ApplicationContext ctx = new ClassPathXMLApplicationContext("applicationContext.xml的路径");
		//获取不同的id来创建对象。创建对象在这一句。获取id相同时,每执行一次getBean就创建一个对象,且每个对象都不同
		User user = (User)ctx.getBean("user");
	}
}

Ioc实现技术:DI

  1. DL:依赖查找,需要在服务器端配置对象的信息,在程序中需要使用特定的类和方法才能获取到服务器中的对象。
  2. DI:依赖注入,在程序中,通过对象的名称就可以获取到对象,至于对象的创建,保存,从容器中查找对象都由容器内部实现

spring框架使用的di这种技术,实现ioc的功能。 spring底层创建对象,赋值属性使用的是jdk中的反射机制。

基于XML的DI

  1. 设值注入
    关键点:实体类需要有set方法
    user.java
public class User{
	private Integer age;
	private String name;
	private Company company;
	--生成set方法--
	public void setEmail(String email){
	}
}

applicationContext.xml

	<bean id="user" class="com.entity.User" >
		<property name="User属性" value="属性值" />  
		<property name="age" value="21" />  <!--这条语句相当于:user.setAge=21-->
		<property name="company" ref="company对应的类的beanID" />  <!-- 对引用类型的设置注入-->
		<property name="email" value="aaa@126.com" />  <!--只要有set方法,也可以在bean中添加相关的属性-->
	</bean>
	<bean id="company" class="com.entity.Company">
	</bean>
  1. 构造注入
    关键点:实体类有带参数的构造方法
public class User{
	private Integer age;
	private String name;
	private Company company;
	--生成含参数的构造方法--
}

applicationContext.xml

	<bean id="user" class="com.entity.User" >
		<constructor-arg name="User属性" value="属性值" />  
		<constructor-arg name="age" value="21" />  <!--这条语句相当于:user.setAge=21-->
		<constructor-arg name="company" ref="company对应的类的beanID" />  <!-- 对引用类型的设置注入-->
	</bean>
	<bean id="company" class="com.entity.Company">
	</bean>
  1. 引用类型自动注入
    引用类型自动注入就是在bean中添加上autowired属性,属性值有两个byName、byType
    1. byName
      传值要求:实体类的引用类型对象 必须作为配置文件中对应引用类型的bean的id值存在 才可以使用
public class User{
	private Integer age;
	private String name;
	private Company company;
	--生成set方法--
}
		applicationContext.xml
	<bean id="user" class="com.entity.User" autowire="byName" >
		<property  name="User属性" value="属性值" />  
		<property  name="age" value="21" />  
		<!--此处引用类型属性可以不用写-->
	</bean>
	<bean id="company" class="com.entity.Company">
	</bean>
  1. byType

传值要求:实体类的引用类型对象 与配置文件中对应引用类型的bean的id值可以不同,只需引用类型相同即可达到传值的目的

public class User{
	private Integer age;
	private String name;
	private Company company;
	--生成set方法--
}
		applicationContext.xml
	<bean id="user" class="com.entity.User" autowire="byType" >
		<property  name="User属性" value="属性值" />  
		<property  name="age" value="21" /> 
		<!--此处引用类型属性可以不用写-->
	</bean>
	<bean id="mycompany" class="com.entity.Company">
	</bean>
  1. 指定多个Spring配置文件
<import  resource="classpath:配置文件路径" />
<import  resource="classpath:配置文件路径" />

基于注解的DI(默认是单例模式)

需要在applicationContext.xml文件中配置context:component-scan 扫描器

<context:component-scan  base-package="使用注解所在的包"  />
<context:component-scan  base-package="com.xx.dao"  />
<context:component-scan  base-package="com.xx.dao,com.xx.service"  /><!--这里也可以使用“;”分隔开-->
<context:component-scan  base-package="com.xx"  /><!--这里也可以使用上级包,或者顶级包:com;缺点:扫描慢-->

可以通过注解达到bean生成对象的结果
@Component(“mystudent”)

  1. 用在实体类上面,使用时可以直接调用id创建对象:getBean(“mystudent”)
  2. 没有小括号,id默认是首字母小写的类名 student
    @Value
    使用在属性上方,不需要set方法也可以赋值。也可以使用在set方法上
    @Repository
    生成持久层对象,用在DAO层,用法同Component
    @Service
    生成业务层对象,用在service层,用法同Component
    @Controller
    生成控制层对象,用在controller层,用法同Component
    @Autowired
    当引用类型作为属性时,自动注入。默认使用byType方式
    @Qualifier(“bean的id”)
    与@Autowired配合使用。
    @Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。
    在这里插入图片描述
    required属性
    @Resource
    @Resource 注解若不带任何参数,采用默认按名称的方式注入,按名称不能注入 bean,则会按照类型进行 Bean 的匹配注入。
    在这里插入图片描述
    @Resource 注解指定其 name 属性,则 name 的值即为按照名称进行匹配的 Bean 的 id。
    在这里插入图片描述

注解与XML的对比

注解优点是:
⚫ 方便
⚫ 直观
⚫ 高效(代码少,没有配置文件的书写那么复杂)。
其弊端也显而易见:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。
XML 方式优点是:
⚫ 配置和代码是分离的
⚫ 在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载。
xml 的缺点是:编写麻烦,效率低,大型项目过于复杂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值