spring_ioc

核心概念

  1. 什么IOC/DI思想?
    • IOC:控制反转,控制反转的是对象的创建权
    • DI:依赖注入,绑定对象与对象之间的依赖关系
  2. 什么是IOC容器?
    • Spring创建了一个容器用来存放所创建的对象,这个容器就叫IOC容器
  3. 什么是Bean?
    • 容器中所存放的一个个对象就叫Bean或Bean对象

IOC xml案例

导入坐标

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.itheima</groupId>
  <artifactId>spring_01_quickstart</artifactId>
  <version>1.0-SNAPSHOT</version>



  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

新建org.gz.dao包,分别实现如下接口和实现类

package org.gz.dao;

public interface BookDao {
    public void save();
}
package org.gz.dao.impl;

import org.gz.dao.BookDao;

public class BookDaoImpl implements BookDao {

    public void save() {
        System.out.println("book dao save ...");
    }
}

新建org.gz.dao包,分别实现如下接口和实现类

package org.gz.service;

public interface BookService {
    public void save();
}
package org.gz.service.impl;

import org.gz.dao.BookDao;
import org.gz.service.BookService;

public class BookServiceImpl implements BookService {
    //5.删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
    //6.提供对应的set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}

启动(测试)类

package org.gz;

import org.gz.dao.BookDao;
import org.gz.dao.impl.BookDaoImpl;
import org.gz.service.impl.BookServiceImpl;

public class App {
    public static void main(String[] args) {
        BookServiceImpl bookService = new BookServiceImpl();
        BookDao bookDao=new BookDaoImpl();
         bookService.setBookDao(bookDao);
        bookService.save();
    }
}

在resource目录下新建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">
    <!--1.导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->

    <!--2.配置bean-->
    <!--bean标签标示配置bean
    id属性标示给bean起名字
    class属性表示给bean定义类型-->
    <bean id="bookDao" class="org.gz.dao.impl.BookDaoImpl"/>

    <bean id="bookService" class="org.gz.service.impl.BookServiceImpl">
        <!--7.配置server与dao的关系-->
        <!--property标签表示配置当前bean的属性
        name属性表示配置哪一个具体的属性
        ref属性表示参照哪一个bean-->
        <property name="bookDao" ref="bookDao"/>
    </bean>

</beans>

新建spring版本的测试类:

package org.gz;

import org.gz.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {
    public static void main(String[] args) {
        //3.获取IoC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //4.获取bean(根据bean配置id获取)
//        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
//        bookDao.save();

        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();

    }
}

运行测试

bean实例化

  • 构造方法实例化bean

 

  • 静态工厂创建对象

 

  • 实例工厂

  • FactoryBean创建对象

 

bean的生命周期

  • 首先理解下什么是生命周期?
    • 从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期。
  • bean生命周期是什么?
    • bean对象从创建到销毁的整体过程。
  • bean生命周期控制是什么?
    • 在bean创建后到销毁前做一些事情。

具体的控制有两个阶段:

  • bean创建之后,想要添加内容,比如用来初始化需要用到资源
  • bean销毁之前,想要添加内容,比如用来释放用到的资源

生命周期控制 -- xml配置 

生命周期控制--接口控制

实现InitializingBean, DisposableBean接口

close关闭容器

  • ApplicationContext中没有close方法,它的子类中有close方法
  • 所以需要将ApplicationContext更换成ClassPathXmlApplicationContext,然后调用close方法就好啦
public class App {
    public static void main(String[] args) {
        //ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao = (BookDao) context.getBean("bookDao");
        bookDao.save();
        context.close();
    }
}

 调用ctx的registerShutdownHook()方法

public class App {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao = (BookDao) context.getBean("bookDao");
        bookDao.save();
        context.registerShutdownHook();
    }
}

不同点:

close()是在调用的时候关闭,registerShutdownHook()是在JVM退出前调用关闭。

注解开发定义bean

步骤一:创建配置类

在配置类上面加一个@Configuration注解,将其标识为一个配置类,用于替换掉applicationContext.XML

在配置类上添加包扫描注解@ComponentScan替换<context:component-scan base-package=""/>

@Configuration
@ComponentScan("org.gz")
public class SpringConfig {
}

步骤一:删除原有的XML配置
将配置文件中的bean标签删除掉

<bean id="bookDao" class="com.blog.dao.impl.BookDaoImpl"/>

步骤二:在Dao上添加注解

在BookDaoImpl类上添加@Component注解(BookDao接口略)

@Component("bookDao")
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
}

注意:@Component注解不可以添加在接口上,因为接口是无法创建对象的。

 步骤五:Service上添加注解

在BookServiceImpl类上也添加@Component交给Spring框架管理(BookServie接口略)


@Component
public class BookServiceImpl implements BookService {

    @Resource
    private BookDao bookDao;

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

步骤四:创建运行类并执行

创建一个新的运行类AppForAnnotation

public class AppForAnnotation {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao = (BookDao) context.getBean("bookDao");
        bookDao.save();
        BookService bookService = context.getBean(BookService.class);
        bookService.save();
    }
}

对于@Component注解,还衍生出了其他三个注解@Controller@Service@Repository
通过查看源码会发现:这三个注解和@Component注解的作用是一样的,为什么要衍生出这三个呢?
这是方便我们后期在编写类的时候能很好的区分出这个类是属于表现层业务层还是数据层的类。

小结

  • 记住@Component@Controller@Service@Repository这四个注解
  • applicationContext.xml中<context:component-san/>的作用是指定扫描包路径,注解为@ComponentScan
  • @Configuration标识该类为配置类,使用类替换applicationContext.xml文件
  • ClassPathXmlApplicationContext是加载XML配置文件
  • AnnotationConfigApplicationContext是加载配置类

bean的作用范围

要想将BookDaoImpl变成非单例,只需要在其类上添加@scope注解

@Component("bookDao")
@Scope("prototype")
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
}

 修改后运行查看结果是否一致

public class AppForAnnotation {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao1 = (BookDao) context.getBean("bookDao");
        BookDao bookDao2 = (BookDao) context.getBean("bookDao");
        System.out.println(bookDao1);
        System.out.println(bookDao2);
    }
}

知识点:@scope

名称@Scope
类型类注解
位置类定义上方
作用设置该类创建对象的作用范围,可用于设置创建出的bean是否为单例对象
属性value(默认):定义bean作用范围,默认值singleton(单例),可选值prototype(非单例)

bean的生命周期

  • 如何对方法进行标识,哪个是初始化方法,哪个是销毁方法?

只需要在对应的方法上添加@PostConstruct@PreDestroy注解即可。

@Component("bookDao")
public class BookDaoImpl implements BookDao {

    public BookDaoImpl() {
        System.out.println("construct ... ");
    }

    public void save() {
        System.out.println("book dao save ...");
    }

    @PostConstruct  // 在构造方法之后执行,替换 init-method
    public void init() {
        System.out.println("init ... ");
    }

    @PreDestroy // 在销毁方法之前执行,替换 destroy-method
    public void destroy() {
        System.out.println("destroy ... ");
    }
}

 要想看到两个方法执行,需要注意的是destroy只有在容器关闭的时候,才会执行,所以需要修改App的类

public class AppForAnnotation {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao = (BookDao) context.getBean("bookDao");
        System.out.println(bookDao);
        context.registerShutdownHook();//关闭容器
    }
}

注意:JDK8版本以上,如果找不到@PostConstruct@PreDestroy注解,需要导入下面的jar包

<dependency>
  <groupId>javax.annotation</groupId>
  <artifactId>javax.annotation-api</artifactId>
  <version>1.3.2</version>
</dependency>

小结

配置文件中的bean标签中的
id对应@Component("")@Controller("")@Service("")@Repository("")
scope对应@scope()
init-method对应@PostConstruct
destroy-method对应@PreDestroy

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值