Spring IoC 入门学习笔记

Spring IoC基础

IoC控制反转
  • loC控制反转,全称Inverse of Control,是一种设计理念
    由代理人来创建与管理对象,消费者通过代理人来获取对象
    loC的目的是降低对象之间直接耦合
    加入loC容器将对象统一管理,让对象关联变为弱耦合
DI依赖注入
  • loC是设计理念,是现代程序设计遵循的标准,是宏观目标
    DI(Dependency Injection)是具体技术实现,是微观实现
    DI在Java中利用反射技术实现对象注入(Injection)
Spring简介
  • Spring框架是企业开发复杂性的一站式解决方案
    Spring框架的核心是loC容器与AOP面向切面编程
    Spring loC负责创建与管理系统对象,并在此基础上扩展功能
Bean的三种配置方式
  • 基于XML配置Bean
    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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 在Ioc容器启动时,自动由Spring实例化Apple对象,取名sweetApple放入到容器中 -->
<!-- bean标签默认通过默认构造方法创建对象 -->
    <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
        <property name="title" value="红富士"></property>
        <property name="origin" value="欧洲"></property>
        <property name="color" value="红色"></property>
    </bean>

XML方式创建IoC容器

 // 创建spring Ioc容器,并根据配置文件在容器中实例化对象
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
  • 利用构造方法参数名实例化
<bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
        <!-- 没有constructor-arg则代表调用默认构造方法实例化 -->
        <constructor-arg name="title" value="红富士"/>
        <constructor-arg name="origin" value="欧洲"/>
        <constructor-arg name="color" value="红色"/>
    </bean>
  • 利用构造方参数位置实例化
<bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
        <constructor-arg index="0" value="红富士"/>
        <constructor-arg index="1" value="欧洲"/>
        <constructor-arg index="2" value="红色"/>
    </bean>
  • 利用静态工厂的静态方法实例化
/**
 * 静态工厂通过静态方法创建对象,隐藏创建对象的细节
 */
public class AppleStaticFactory {
    public static Apple createSweetApple(){
        //logger.info("")
        Apple apple = new Apple();
        apple.setTitle("红富士");
        apple.setOrigin("欧洲");
        apple.setColor("红色");
        return apple;
    }
}
<!--利用静态工厂获取对象-->
    <bean id="apple4" class="com.imooc.spring.ioc.factory.AppleStaticFactory"
          factory-method="createSweetApple"/>
  • 利用工厂实例方法创建对象
**
 * 工厂实例方法创建对象是指IoC容器对工厂类进行实例化并调用对应的实例方法创建对象的过程
 */
public class AppleFactoryInstance {
    public Apple createSweetApple(){
        Apple apple = new Apple();
        apple.setTitle("红富士");
        apple.setOrigin("欧洲");
        apple.setColor("红色");
        return apple;
    }
}
<!--利用工厂实例方法获取对象-->
    <bean id="factoryInstance" class="com.imooc.spring.ioc.factory.AppleFactoryInstance"/>
    <bean id="apple5" factory-bean="factoryInstance" factory-method="createSweetApple"/>
  • 从IoC容器中获取Bean
// 初始化spring Ioc容器,并根据配置文件在容器中实例化对象
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Apple sweetApple = context.getBean("sweetApple", Apple.class);
        // 单参数方法获得Bean
        Apple sweetApple1 = (Apple) context.getBean("sweetApple");
        System.out.println(sweetApple.getTitle());
  • bean标签中id与name属性相同点
    bean id与name都是设置对象在loC容器中唯一标识
    两者在同一个配置文件中都不允许出现重复
    两者允许在多个配置文件中出现重复,新对象覆盖旧对象
  • bean标签中id与name属性不同点
    id要求更为严格,一次只能定义一个对象标识(推荐)
    name更为宽松,—次允许定义多个对象标识
    tips: id与name的命名要求有意义,按驼峰命名书写
  • 在IoC容器初始化时加载多个配置文件
 		String[] configLocations = new String[]{"classpath:applicationContext.xml", "classpath:applicationContext-1.xml"};
       	ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);

注:没有id与name的bean默认使用类名全称作为bean标识,即class属性的值。

  • 路径表达式
    classpath: 指向了target目录下的classes文件夹。
    classpath:config.xml: 扫描classpath根路径(不包含jar)的config.xml
    classpath:com/imooc/config.xml: 扫描classpath下(不包含jar)com.imooc包中的config.xml
    classpath*:com/imooc/config.xml: 扫描classpath下(包含jar)com.imooc包中的
    config.xml
    classpath:config-*.xml: 扫描classpath根路径下所有以config-开头的XML文件
    classpath:com/**/config.xml: 扫描com包下(包含任何子包)的config.xml
    file:c:/config.xml: 扫描c盘根路径config.xml
  • 对象依赖注入
    依赖注入是指运行时将容器内对象利用反射赋给其他对象的操作
    基于setter方法注入对象
    基于构造方法注入对象

使用stter方法注入对象有两种情况:

  1. 利用setter实现静态数值注入
<bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
<! -- Ioc容器自动利用反射机制运行时调用setXXX方法为属性赋值-->
<property name="title" value="红富士"/>
<property name="color" value="红色"/>
<property name="origin" value="欧洲"/>
// Ioc 的value属性可以自动调用Apple.java类中的set方法,将"红富士"赋值给了title属性,所以在getTitle时可以直接得到title的值。
Apple sweetApple = context.getBean ( s: "sweetApple"Apple.class);
system.out.println (sweetApple.getTitle ( ) ) ;
// 输出是红富士
  1. 利用setter实现对象注入
<bean id="lily" class="com. imooe.spring.ioc.entity.Child">
<property name="nane" value="莉莉" />
 <!-- 利门rel注入依赖对象 -->
<property name="apple" ref="sweetApple" />
</bean>
  • 注入集合对象
    注入List
<!-- 生成的数据类型为ArrayList -->
<bean id="..." class="...">
<property name= "someList" >
<list>
<value>具体值</value>
<ref bean="beanld"></ref>
</list>
</property>
</bean>

注入Set

<!-- 生成的数据类型为LinkedHashSet -->
<bean id="..." class="...">
<property name="someSet" >
<set>
<value>具体值</value>
<ref bean="beanld"></ref>
</set>
</property></bean>

注入Map

<!-- 生成的数据类型为LinkedHashMap -->
<bean id="..." class="..." >
<property name="someMap">
<map>
<entry key="k1" value="v1"></entry>
<entry key="k2" value-ref="beanld" ></entry >
<!-- 内部bean,没有beanid只能在这个map标签中使用,不能被外部引用 -->
<entry key="dev-88173">
<bean class="com.imooc.spring.ioc.entity.Computer">
<constructor-arg name="brand" value="联想"/>
<constructor-arg name="type" value="笔记本"/><constructor-arg name="sn" value="1280258012"/><constructor-arg name="price" value="5060" />
</bean>
</entry>
</map>
</property>
</bean>

注入Properties

<!-- 用于保存String字符串类型 -->
<bean id="..." class="...">
<property name= "someProperties">
<props>
<prop key="k1">v1</prop>
<prop key="k2" >v2</prop>
</props>
</property>
</bean>
  • 查看Ioc 容器里的Bean内容
//返回一个获取容器内所有beanId的String数组
string[] beanNames = context.getBeanDefinitionNames();
  • bean scope 属性
    bean scope属性用于决定对象何时被创建与作用范围
    bean scope配置将影响容器内对象的数量
    默认情况下bean会在loC容器创建后自动实例化,全局唯一
<bean id="bookDao"
class="com.imooc.spring.ioc.bookshop.dao.BookDaoOraclelmpl"scope="prototype" />

singleton
单例(默认值),每一个容器有且只有唯一的实例,实例被全局共享
prototype
多例,每次使用时都是创建一个实例
request
web环境下,每一次独立请求存在唯一实例
session
web环境下,每一个session存在有唯一实例
global session
portlet的web应用的共享session中
websocket
每一次WebSocket连接中存在唯一实例

  • singleton 与 prototype 对比
    截图来自慕课网
    默认的singleton属性会让bean在配置文件加载的时候就初始化。
    prototype属性会让配置的bean只在被关联到或者getbean方法调用的时候才初始化
  • bean的生命周期
    截图来自慕课网
    prototype时对象创建与init-method延迟至执行业务代码阶段
    prototype时对象不再受loC容器管理,不会触发destroy-method
    延迟加载lazy-init属性可让对象创建与初始化延迟到执行代码阶段
  • 基于注解配置Bean
    摆脱繁琐的XML形式的bean与依赖注入配置
    基于"声明式"的原则,更适合轻量级的现代企业应用
    让代码可读性变得更好,研发人员拥有更好的开发体验
  • 三类注解
    组件类型注解-声明当前类的功能与职责
    自动装配注解-根据属性特征自动注入对象
    元数据注解-更细化的辅助loC容器管理对象的注解
  • 组件类型注解
    @Component: 组件注解,通用注解,被该注解描述的类将被loC容器管理并实例化
    @Controller: 语义注解,说明当前类是MVC应用中的控制器类
    @Service: 语义注解,说明当前类是Service业务服务类
    @Repository: 语义注解,说明当前类用于业务持久层,通常描述对应Dao类

开启组件扫描

<!--XML配置开启组件扫描,才能使用注解-->
<context:component-scan base-package="com.imooc">
<!-- 对一些文件排除在组件扫描之外 -->
<context:exclude-filter type="regex" expression="com.imooc.exl.*" /></context:component-scan>

例子:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 基于注解的schema约束和xml的不同。 -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- xmlns:context="http://www.springframework.org/schema/context" 为设置一个叫context的命名空间。 -->
    <context:annotation-config/>
    <!-- 在Ioc容器初始化时自动扫描四种组件类型注解并完成实例化
    @Repository
    @Service
    @controller
    @Component
    -->

    <context:component-scan base-package="com.imooc"/>
</beans>
import org.springframework.stereotype.Repository;
// 组件类型注解默认beanId为类名首字母小写
// beadld = userDao
// 设置指定的beanUd: @Repository("udao")

@Repository
public class UserDao {
}
  • 自动注解装配
    按类型装配:
    @Autowired: 按容器内对象类型动态注入属性,由Spring机构提供
    @Inject: 基于JSR-330(Dependency lnjection for Java)标准, 其他同@Autowired,但不支持required属性
    按名称装配:
    @Named: 与@Inject配合使用,JSR-330规范,按属性名自动装配属性
    @Resource: 基于JSR-250规范,优先按名称、再按类型智能匹配
// Spring IoC容器会自动通过反射技术将属性private修饰符自动改为public,直接进行赋值
//不再执行set方法
@Autowired
private UserDao udao ;
public UserDao getUdao (){
return udao;
@Autowired
//如果装配注解放在set方法上,则自动按类型
//名称对set方法参数进行注入
public void setUdao (UserDao udao){
System.out.println ( "setUdao : " t udao) ;
this.udao = udao;
)
}
/**
* 1.@Resource设置name属性,则按name在IoC容器中将bean注入* 2.@Resource未设置name属性
* 2.1以属性名作为bean name在Ioc容器中匹配bean ,如有匹配则注入
* 2.2按属性名未匹配,则按类型进行匹配,同@Autowired,需加入ePrimary解决类型冲突*使用建议:在使用@Resource对象时推荐设置name或保证属性名与bean名称一致
**/

// @Resource (name = "useroracleDao")
@Resource
private IUserDao userOracleDao;
  • 元数据注解
    @Primary: 按类型装配时出现多个相同类型对象,拥有此注解对象优先被注入
    @PostConstruct: 描述方法,相当于XML中init-method配置的注解版本
    @PreDestroy: 描述方法,相当于XML中destroy-method配置的注解版本
    @Scope: 设置对象的scope属性
    @Value: 为属性注入静态数据
  • 基于Java Config代码配置Bean
    完全摆脱XML的束缚,使用独立Java类管理对象与依赖
    注解配置相对分散,利用Java Config可对配置集中管理
    可以在编译时进行依赖检查,不容易出错

Java Config核心注解
@Configuration: 描述类,说明当前类是Java Config配置类,完全替代XML文件
@Bean: 描述方法,方法返回对象将被loC容器管理,beanld默认为方法名
@lmportResource: 描述类,加载静态文件,可使用@Value注解获取
ComponentScan: 描述类,同XML的<context:compoment-scan>标签

// 配置类的代码
@Configuration
//当前类是一个配置类,用于替代applicationContext.xml
public class Config {
@Bean //Java Config利用方法创建对象,将方法返回对象放入容器, beanId=方法名
public UserDao userDao(){
UserDao userDao = new UserDao();
return userDao;
}
@Bean
public Userservice userservice() {
UserService userService = new UserService();return userService;
}
@Bean
public UserController userController() {
UserController userController = new UserController() ;return userController;
}
}

// 加载配置类的代码
//基于Java Config配置ioc容器的初始化
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
  • Spring Test 测试模块
    Spring Test是Spring中用于测试的模块
    Spring Test对JUnit单元测试框架有良好的整合
    通过Spring Test可在JUnit在单元测试时自动初始化loC容器

Spring 与 JUnit4 整合
Maven工程依赖spring-test
利用@RunWith与@ContextConfiguration描述测试用例类
测试用例类从容器获取对象完成测试用例的执行

需要的依赖

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

例子测试代码

在这里插入代码片// 将Junit4的执行权交由spring Test,在测试用例执行前自动初始化IoC容器
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class SpringTestor {

    @Resource
    private UserService userService;

    @Test
    public  void testUserService(){
        userService.createUser();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值