Spring学习之IOC与DI

什么是框架?
  ●框架就是一些类和接口的集合,通过这些类和接口协调来完成一系列的程序实现。JAVA框架可以分为三层:表示层,业务层和物理层。框架又叫做开发中的半成品,它不能提供整个WEB应用程序的所有东西,但是有了框架,我们就可以集中精力进行业务逻辑的开发而不用去关心它的技术实现以及一些辅助的业务逻辑。也可以理解成修房子,先把房子的樑、柱子建起来,这就是一个房子的框架。
  
菜鸟,你知道spring的核心思想是什么吗?
spring的理解:
  ●spring框架就是一个容器,这个容器最主要的作用就是创建对象,以前我们创建对象时通过new关键字,现在不需要这么麻烦了,只需要找到这个容器就可以找到你需要的对象,其实就是一个factory,这个工厂可以提供很多我们需要的对象,我们只需要知道对象对应的名字就行了。主要就是通过搜索class的路径。找出bean对象,实际就是根据反射来获取这个bean对象的:

Class<?> classit=Class.forName("com.jinglin.spring_01.model.Person");
Person p =(Person)classit.newInstance();

AOP是什么
  ●AOP: (Aspect Oriented Programming) 面向切面编程。是目前软件开发中的一个热点,也是spring框架中容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。

1.1 IoC是什么
  ●Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
  ●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

  ●为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
1.2 IoC能做什么
  IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

  其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

  IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

1.3 IoC和DI
  DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

  理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:
  ●谁依赖于谁:当然是应用程序依赖于IoC容器;
  ●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;
  ●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;
  ●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
  IoC和DI有什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
大家有兴趣可以去看看这篇博客《谈谈对spring IOC的理解

对于Spring中的bean的注入方式
  1 set方式注入,注入数据的前提是必须要有一个set方法,在bean的类里。是通过属性的注入方式:
java类

package com.jljy.spring_01.model;

import java.util.List;
import java.util.Map;

public class Boy {
    private String name;//姓名
    private Girl girlFriend;//女盆友
    private Map<String, Float> subject;//学科成绩
    private List<String> hobbies;//爱好

    public Map<String, Float> getSubject() {
        return subject;
    }

    public void setSubject(Map<String, Float> subject) {
        this.subject = subject;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public Girl getGirlFriend() {
        return girlFriend;
    }

    public void setGirlFriend(Girl girlFriend) {
        this.girlFriend = girlFriend;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

  2 构造函数的注入,初始化对象的时候通过构造函数传入数据:

public Boy(String _name,Integer _age){
        this.name=_name;
        this.age=_age;
    }

由spring给我们提供的bean对象的作用域
1)默认情况下,spring提供的bean对象是共享模式的。
在内存中只出现一个实例化对象。
默认的bean的作用域:scope=”singleton”
2)如果更改bean的作用域,就是非共享模式,
scope=”prototype”

这里写图片描述

自动装配+注解,简化spring中的bean对象的开发。
Spring中的bean对象自动从容器里搜索和自己的属性字段名一致的情况,如果有,就自动匹配。
开发步骤,首先明确,要将所有的包扫描的spring容器里。
1)在applicationContext.xml里做spring的beans的声明:

<beans
xmlns="http://www.springframework.org/schema/beans"   
    xmlns:p="http://www.springframework.org/schema/p"   
    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   
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

将各个包扫描到spring里:

<!-- 将包扫描到spring组件里 -->
    <context:component-scan base-package="com.jinglin.dao">
    </context:component-scan>
    <context:component-scan base-package="com.jinglin.service">
    </context:component-scan>

给每个类加入注解,告诉spring。将其加入到spring的容器里:

@Component("goodsInfoDao")
public class GoodsInfoDao {
   public void insertitem(){
       System.out.println("这是商品信息的数据插入");
   }
}

为了简化配置,采取的自动装配。一般都是通过名字自动装配的:

<!-- 这里默认为no-->
default-autowire="byName"

在开发的时候,对于同spring中相同的bean的id,那么采取自动装配:

@Component("userInfoService")
public class UserInfoService {
    @Autowired
    private UserInfoDao userInfoDao;
    public void additem(){
        System.out.println("这是用户调用的业务层");
        userInfoDao.insertitem();
    }
}

Spring的延迟加载,当我们需要这个spring提供的bean对象的时候,这个时候spring才会去生成这个对象(默认情况下,当spring加载它的文件的时候,就全部将spring里配置的bean对象生成)。
1)在applicationContext配置:

<beans default-lazy-init="true">

2)针对单个的bean对象:

<bean id="person" lazy-init="true"  class="com.jinglin.model.Person">
        <!-- 通过构造参数的方式注入值 -->
        <constructor-arg value="zhangsan"></constructor-arg>
        <constructor-arg value="14"></constructor-arg>
    </bean>

3)直接在类中加注解,表示就是延迟加载。

@Component("goodsInfoService")
@Lazy
public class GoodsInfoService {
    @Autowired
    private GoodsInfoDao goodsInfoDao;
    public void additem(){
        System.out.println("这是商品信息的业务处理方法");
       goodsInfoDao.insertitem();
    }

    public GoodsInfoService(){
        System.out.println("这是goodsInfoService的无参构造函数");
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值