Spring - IOC

作者: 阿敏MIN | 来源:发表于2018-09-21 00:15 被阅读12次
image.png

spring framwork


一、认识spring

Spring Framwork

1.spring是一个开源JavaEE框架

2.spring是一个轻量级、一站式框架

  • 一站式:spring框架对象的每一层都提供解决方案
    • 显示层:spring mvc
    • 业务层解决方案:ioc(Inversition Of Control 控制反转 - 对象创建的控制权由用户转移到spring容器)
    • 数据层解决方案:jdbcTamplate

3.spring框架核心功能

  • IOC(Inversition Of Control )控制反转 : 对象创建的控制权由用户转移到spring容器
  • AOP(Aspect Oriented Programing)面向切面编程 : 对功能扩展不通过修改源代码实现,而是动态植入进来

4.学习版本:spring4.3.2

总结:spring是一个开源、轻量级、一站式框架;核心功能为IOC和AOP

二、IOC入门

1.初识

⑴加载IOC模块Jar包 beans | core | contenxt | expression | commons-logging
⑵编写spring核心配置文件

spring框架默认配置文件名称:ApplicationContext.xml,但spring框架对配置文件名称是没有要求的;配置需求引入相关模块约束(必须)spring框架配置文件的约束使用Schema;
配置文件约束:

<?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">
    <!-- id:唯一标识;class:类全路径 -->
    <bean id="dept" class="cn.lanqiao.ioc.Dept"></bean>
</beans>
⑶从spring容器中获取bean
//1.根据spring核心配置文件创建一个spring容器对象;
String configLocation = "spring-core.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);
//2.从容器中获取bean 手动 - 自动注入
Dept dept = context.getBean("dept",Dept.class);

2.spring ioc工作原理

⑴在配置文件(*.xml)写<bean></bean>;
⑵加载并解析配置文件,拿到创建bean;
⑶使用反射创建bean对象并放到容器中;

User u = new User();
<bean id="u" class="全路径User"></bean>
image.png

三.IOC进阶

1.bean对象的三种创建

⑴Instantiation with a constructor【无参构造方法创建 - 主要使用
package cn.lanqiao.ioc;
//javabean:有get | set | 有无参构造方法
public class Dept {
    private Integer deptno;
    private String dname;
    private String loc;
    public Dept() {
        System.out.println("无参构造方法");
    }

    public Integer getDeptno() {
        return deptno;
    }
    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }
    public String getDname() {
        return dname;
    }
    public void setDname(String dname) {
        this.dname = dname;
    }
    public String getLoc() {
        return loc;
    }
    public void setLoc(String loc) {
        this.loc = loc;
    }
    @Override
    public String toString() {
        return "Dept [deptno="+deptno+",dname="+dname+",loc="+loc+"]";
    }
}

<!-- ⑴默认无参构造方法创建实例 -->
<!-- 要求类中有无参构造方法 -->
<bean id="dept1" class="cn.lanqiao.ioc.Dept"></bean
⑵Instantiation using a static factory method【静态工厂创建bean】

何时用:实际开发中,使用第三方jar包提供给类无构造方法,而是通过第三方包提供的静态工厂创建;这时想把第三方jar类交由spring来管理,可以使用Spring提供的静态工厂创建实例的配置

package cn.lanqiao.ioc;

public class BeanStaticFactory {
    public static Dept instance() {
        return new Dept();
    }
}
<!-- ⑵静态工程创建实例 -->
<bean id="dept1" class="cn.lanqiao.ioc.BeanStaticFactory" factory-method="instance"></bean>
  • factory-method:该工厂类创建Bean的静态方法public static Dept instance()
⑶Instantiation using an instance factory method【实例工厂创建bean】

何时用:实际开发中,Spring整合mybatis就是通过这种方式实现

package cn.lanqiao.ioc;

public class BeanInstanceFactory {
    public Dept instance() {
        return new Dept();
    }
}
<!-- ⑶通过实例工厂创建bean -->
<bean id="instanceFactory" class="cn.lanqiao.ioc.BeanInstanceFactory"></bean>
<bean id="dept3" factory-bean="instanceFactory" factory-method="instance"></bean>

factory-method:该工厂类创建Bean的普通方法public Dept instance()

⑴⑵⑶注意:加载配置文件的时候就创建了实例

2.bean节点的几个主要属性

<bean id="" class="" scope="" > </bean>
  • id | name:bean唯一标识(name与id相比,name可以放一些特殊字符)
  • class:类的全路径
  • scope:bean作用域
    • singleton(默认单例):在Spring的IOC容器中只存一个对象实例,对象引用都共享实例(多个构造方法)
    • prototype(多例):每次对该bean的请求都会创建一个新的实例(单个构造方法)
    • 以下只能在web应用程序中使用:request | session | application | globalSession | websocket

3.bean对角注入数据 - bean属性赋值,模拟获取数据值

⑴通过属性注入属性 [实际开发使用]

注入简单类型数据

<bean id="dept2" class="cn.lanqiao.ioc.Dept">
    <property name="deptno" value="101"></property>
    <property name="dname" value="财务"></property>
    <property name="loc" value="汕头"></property>
</bean>
⑵通过构造方法注入属性
    public Dept(Integer deptno) {
        this.deptno = deptno;
        System.out.println("有参构造方法"+deptno);
    }
    
    public Dept(Integer deptno,String dname) {
        this(deptno);
        this.dname = dname;
        System.out.println("有参构造方法"+dname);
    }
    public Dept(Integer deptno,String dname,String loc) {
        this(deptno,dname);
        this.loc = loc;
        System.out.println("有参构造方法"+loc);
    }
<bean id="dept3" class="cn.lanqiao.ioc.Dept">
    <!-- 属性名-值 -->
    <!-- 
        <constructor-arg name="deptno" value="101"></constructor-arg>
        <constructor-arg name="dname" value="财务"></constructor-arg>
        <constructor-arg name="loc" value="汕头"></constructor-arg> 
    -->
    <!--  数组坐标-值 -->
        <constructor-arg index="0" value="101"></constructor-arg>
        <constructor-arg index="1" value="财务"></constructor-arg>
        <constructor-arg index="2" value="汕头"></constructor-arg>
</bean>
⑶注入对象
package cn.lanqiao.ioc;

public class DeptDao {
    public void addDept(Dept dept) {
        System.out.println("dao实现了添加dept");
    }
}

package cn.lanqiao.ioc;

public class DeptService {
    //注入数据
    private DeptDao dao;
    //通过属性注入对象

    public void add(Dept dept) {
        dao.addDept(dept);
    }
    public DeptDao getDao() {
        return dao;
    }

    public void setDao(DeptDao dao) {
        this.dao = dao;
    }
    
}

<bean id="deptDao" class="cn.lanqiao.ioc.DeptDao"></bean>
<bean id="daoService" class="cn.lanqiao.ioc.DeptService">
        <property name="dao" ref="deptDao"></property>
</bean>
⑷自动装配

针对对象的注入 : 自动给注入对象属性赋值 = 注入对象 + 自动配置实例类的属性名

  • 根据对象类型autowire="byType"自动注入:无要求;
image.png
<bean id="deptService" class="cn.lanqiao.ioc.DeptService" autowire="byType" />
  • 根据对象名称autowire="byName"注入要求:注入数据的对象名与bean的id一致;
image.png
<bean id="deptService" class="cn.lanqiao.ioc.DeptService" autowire="byName" />

4.注入复杂对象 [只需了解]

bean | ref | idref | list | set | map | props | value | null

5.p-namespace [实际开发少用,但相对以上方法要便利]

何时用:注入数据(属性值)的时候

要使用p标签给属性赋值,需要引入p标签namespace

约束: xmlns:p="http://www.springframework.org/schema/p"

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close"
        p:driverClassName="com.mysql.jdbc.Driver"
        p:url="jdbc:mysql://localhost:3306/mydb"
        p:username="root"
        p:password="masterkaoli"/>
</beans>
<bean id="dept" class="cn.lanqiao.ioc.Dept" p:deptno="1001" p:dname="人事" p:loc="北京" />

6.ioc的注解开发(实际开发使用)

第一步:加载JAR包 spring-aop-4.3.2.RELEASE.jar
第二步:引入注解约束
  • xmlns:context="http://www.springframework.org/schema/context"
  • http://www.springframework.org/schema/context
  • http://www.springframework.org/schema/context/spring-context.xsd
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd 
         http://www.springframework.org/schema/context 
         http://www.springframework.org/schema/context/spring-context.xsd">
 </beans>
第三步:启用注解扫描

作用:使在其他类中的注解生效,相当于类与IOC容器(.xml文件)相关联

<context:component-scan base-package="cn.lanqiao.ioc.anno"/> 
第四步:在bean上添加注解
Ⅰ.@Component介绍

有什么用?

为类取名字(首字母小写的类名deptDao),方便在IOC容器使用

例如 规范类名:DeptDao = IOC容器取类名:deptDao

@Component(value="对象名")

= <bean id=" 对象名 " class=" 类的全路径 "></bean>

= 对象名;

  • @Repository : 一般加载数据层

  • @Service :一般加载业务层;

  • @Controller:一般加载控制层

@Component = @Repository = @Service = @Controller


Ⅱ.@Resource介绍

有什么用?

注入对象 = 实例化对象 = 类中引入其他类并实例化

例如 User u = new User();

@Resource(name="注入的对象名") :根据name注入(byName)

= <bean id="对象名" class="类的全路径">

  <property name="`注入的对象名`" ref="对象名"></property>

</bean>

= new 注入的对象名();

@Autowired :根据类型注入(byTyppe)

=<bean id="对象名" class="类的全路径" autowire="byType"></bean>

= new 对象名() + package 类的全路径;

@Qualifier(value="注入对象名") + @Autowired = @Resource


Ⅲ.@Scope介绍

有什么用?

作用域:在代码中涉及到对象间是否数据共享;

​ 在网页中,涉及到数据在页面间是否共享;

  • @Scope(value="singleton")
    • singleton 默认单例,共享一个实例
    • prototype 多例,每次实例化都是新的对象

相关文章

网友评论

    本文标题:Spring - IOC

    本文链接:https://www.haomeiwen.com/subject/hrdzgftx.html