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

<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">


    <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 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="莉莉" />
 
<property name="apple" ref="sweetApple" />
bean>
  • 注入集合对象
    注入List

<bean id="..." class="...">
<property name= "someList" >
<list>
<value>具体值value>
<ref bean="beanld">ref>
list>
property>
bean>

注入Set


<bean id="..." class="...">
<property name="someSet" >
<set>
<value>具体值value>
<ref bean="beanld">ref>
set>
property>bean>

注入Map


<bean id="..." class="..." >
<property name="someMap">
<map>
<entry key="k1" value="v1">entry>
<entry key="k2" value-ref="beanld" >entry >

<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


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

开启组件扫描


<context:component-scan base-package="com.imooc">

<context:exclude-filter type="regex" expression="com.imooc.exl.*" />context:component-scan>

例子:



<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">
    
    <context:annotation-config/>
    

    <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的标签

// 配置类的代码
@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.springframeworkgroupId>
            <artifactId>spring-testartifactId>
            <version>5.2.6.RELEASEversion>
        dependency>

        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        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();
    }
}

你可能感兴趣的:(JAVA基础知识学习笔记,spring,学习,java)