spring01_02_SpringIOC解耦(含源码下载)

先上代码:项目源码下载(软件:IDEA):

1.[理解]自定义IOC实现程序解耦合

链接:https://pan.baidu.com/s/1in10JR4D_muZHyWGPzaj9Q 
提取码:lvgt 

2.[掌握]使用SpringIOC实现程序解耦合

链接:https://pan.baidu.com/s/1OU3YqT1FADIC8SagMumpWQ 
提取码:pen8 

[理解]IOC的概念和作用

注意:IOC和AOP不是从Spring开始才有的,在Spring之前更趋向于理论化,在Spring这才发扬光大的

    IOC的概念

    IOC:inverse of control (反转控制/控制反转),我们之前在一个java类中通过new的方式去引入外部资源(其他类等),这叫正向;现在Spring框架帮我们去new,你什么时候需要你去问Spring框架要,这就是反转(创建对象权利的一个反转)

    我们丧失了一个权利(主动创建对象的权利),但是我们拥有了一个福利(我们不用考虑对象的创建、销毁等问题)

    IOC的作用

    IOC解决程序耦合问题

    关于程序耦合(有一个认识即可)

    耦合:耦合度的意思,程序当中:为了实现一个业务功能,不同的模块之间互相调用就会产生耦合。

    注意:耦合是不能避免的,耦合尽可能去降低

    “高内聚、低耦合”,内聚度过高不利于代码复用,内聚度往往通过增加方法来完成(麻烦自己、方便别人)

[理解]自定义IOC实现程序解耦合
 

pojo对象

package com.itheima.pojo;
public class Account {
    private Integer id;
    private String name;
    private Float money;
    public Account() {
    }
    public Account(Integer id, String name, Float money) {
        this.id = id;
        this.name = name;
        this.money = money;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Float getMoney() {
        return money;
    }
    public void setMoney(Float money) {
        this.money = money;
    }
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

 service层

package com.itheima.service;
import com.itheima.pojo.Account;
public interface AccountService {
    void saveAccount(Account account);
}
package com.itheima.service;
import com.itheima.dao.AccountDao;
import com.itheima.dao.AccountDaoImpl;
import com.itheima.pojo.Account;
public class AccountServiceImpl implements  AccountService{
    /*
        这里有耦合
            new AccountDaoImpl()把AccountServiceImpl对象和AccountDaoImpl耦合在一起
     */
    AccountDao accountDao = new AccountDaoImpl();
    @Override
    public void saveAccount(Account account) {
        accountDao.saveAccount(account);
    }
}

dao层

package com.itheima.dao;

import com.itheima.pojo.Account;

public interface AccountDao {
    /*
        保存账户信息

     */
    void saveAccount(Account account);
}
package com.itheima.dao;

import com.itheima.pojo.Account;

public class AccountDaoImpl implements AccountDao{
    @Override
    public void saveAccount(Account account) {

        System.out.println("保存了账户信息");
    }
}

bean工厂

/**
 *  bean工厂
 *    读取xml信息
 *    反射创建对象
 *    存储到集合Map (对象容器)
 *
 *    提供一个方法,根据id获取对象
 */
public class BeanFactory {
    private static  Map<String,Object> map = new HashMap<String, Object>();

    /**
     *  读取xml配置文件
     *  创建对象,存储Map集合
     */
    static {
        InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(in);
            Element rootElement = document.getRootElement();
            List<Element> elementList = rootElement.selectNodes("//bean");
            if(elementList != null && elementList.size() >0 ){
                for(Element element : elementList){
                    String id = element.attributeValue("id");
                    String className = element.attributeValue("class");
                    Class clazz = Class.forName(className);
                    Object obj = clazz.newInstance();
                    map.put(id,obj);
                }
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *  根据id返回对象
     */
    public static  Object getInstance(String id){
        return map.get(id);
    }
}

beans.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!--
   存储需要实例化的对象
   id 唯一标识
   class 类全限定名
-->
<beans>
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
</beans>

[掌握]使用SpringIOC实现程序解耦合

  1. 引入jar坐标
        <!--需要spring作为容器  完成IOC这种操作-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>

    Spring-context的依赖包会自动引入,这就是maven的依赖传递

service层和dao层的业务代码完善
实例化service和dao代码,把它们的信息写在spring配置文件中

引入spring的jar之后,idea中会自动有这个配置文件模板

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 id="accountService" class="com.itheima.service.impl.AccountServiceImpl"></bean>
<bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean>
</beans>

测试类

/**
 * 测试springIOC容器
 */
@Test
public void testIOC(){
   // ApplicationContext对象容器
   ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
   // getBean方法获取对象
    AccountService service = (AccountService) context.getBean("accountService");
    AccountDao dao = (AccountDao)context.getBean("accountDao");
    /*
      接口class获取实现类对象,接口只有一个实现类
      context.getBean(AccountService.class);
    */
    /*
      接口class获取实现类对象
      id唯一标识
       context.getBean("accountService",AccountService.class);
    */
    System.out.println(service);
    System.out.println(dao);
    }
}

[掌握]SpringIOC的一些细节知识

ApplicationContext和BeanFactory

    ApplicationContext:立即加载模式,在Spring启动的时候会立即实例化对象,等待使用,推荐使用

    BeanFactory:使用到对象的时候(getBean等)才去实例化对象(延迟加载模式),不推荐的

    简单说:

    创建对象的时间点不一样

        ApplicationContext:配置文件一旦读取完了,默认就会创建对象放到容器中。

        BeanFactory:什么时候用对象,什么时候创建。

Bean标签

    id:标识符

    class :实例化类的全限定类名,供反射实例化使用

    scope :对象的使用范围

    singleton:默认值,单例,项目全局内存中只有一个对象,一般在使用Spring的时候保持默认值即可

    prototype:原型的意思,在这里是多例,每引用或者getBean一次,Spring框架就返回一个新的对象,比如SqlSession这个特殊的对象
    request:这种配置针对web应用,每一个request范围内只对应一个对象
    session:这种配置针对web应用,每一次会话该bean只有一个对象
    global session:针对的是portlet环境,等同于servlet下的session

生命周期属性

nit-method指定初始化时执行的方法

destory-method指定销毁时执行的方法

注意:容器的close方法在实现类当中

注意测试destory销毁方法的时候,scope配置为单例

对象创建的三种方式

1.通过配置class全限定类名框架底层使用反射技术来创建对象(经常使用,推荐)

<bean id="accountService" class="com.itheima.service.AccountServiceImpl"></bean>
<bean id="accountDao" class="com.itheima.dao.AccountDaoImpl"></bean>

2.静态方法(自己new对象,然后加入到Spring的对象容器中管理)

3.动态方法(自己new对象,然后加入到Spring的对象容器中管理)(需要首先定义工厂的bean,然后通过工厂bean对象调用里面的方法返回具体对象)

依赖注入(DI)

DI: dependance inject(依赖注入的意思)

IOC和DI的区别

IOC和DI是一个事情,只是描述的角度不同(面试题)

Set注入(也叫设值注入,这是常用和推荐的用法)(必须练习!!)

构造函数注入(了解 不常用)

p约束的注入方式

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

在标签里面使用这个约束

<bean id="accountService" class="com.itheima.spring.service.AccountServiceImpl" p:name="翟天临" p:id="3" p:money="111.111" p:accountDao-ref="accountDao">
</bean>
<bean id="accountDao" class="com.itheima.spring.dao.AccountDaoImpl"/>

复杂对象注入

<!-- 完成 复杂类型的 set依赖注入-->
<property name="myStrs">
    <array>
       <value>翟天临</value>
        <value>吴秀波</value>
        <value>黄海波</value>
    </array>
</property>
<property name="myList">
    <list>
        <value>list1</value>
        <value>list2</value>
        <value>list3</value>
    </list>
</property>
<property name="mySet">
    <set>
        <value>set1</value>
        <value>set2</value>
        <value>set3</value>
    </set>
</property>
<property name="myMap">
    <map>
        <entry key="1" value="张三"></entry>
        <entry key="2" value="李四"></entry>
    </map>
</property>
<property name="myPros">
    <props>
        <prop key="1">王五</prop>
        <prop key="2">钱七</prop>
    </props>
</property>

private String[] myStrs;
private List<String> myList;
private Set<String> mySet;
private Map<String,String> myMap;
private Properties myProps;

注意:list、set和array是一类数据类型,单值型,所以在Spring注入的时候,<array><list><set>可以替换使用;map和properties都是key/value类型的,所以<map>和<props>标签可以替换使用。但是以上替换不建议,没有意义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_35670694

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值