Spring之IOC

1.1简介

2002年,首次推出了spring框架的雏形,interface21框架

spring框架以interface21框架为基础经过重新设计,并不断丰富其内涵于于2004年3月24日发布了1.0正式版

Rod johnson 是spring Framework创始人,著名作者,他是悉尼大学博士,音乐专业,并非计算机。

spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!

SSH:struct2+spring+Hibernate

SSM:springMVC+spring+Mybatis

官网:https://spring.io/projects/spring-framework#overview

官方下载地址: http://repo.spring.io/release/org/springframework/spring

GitHub:https://github.com/spring-projects/spring-framework

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>   
<groupId>org.springframework</groupId>    <artifactId>spring-webmvc</artifactId>    <version>5.2.0.RELEASE</version>
</dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>    
<groupId>org.springframework</groupId>    <artifactId>spring-jdbc</artifactId>    <version>5.2.0.RELEASE</version>
</dependency>
优点

spring是一个开源免费的框架

spring是一个轻量级的,非入侵式的框架

控制反转(ioc),面向切面编程(aop)

支持事务的处理,对框架整合的支持

Spring就是一个轻量级的控制反转(IOC),和面向切面编程(AOP)的框架

组成

Spring AOP

Spring ORM

Spring Web

Spring WEB MVC

Spring DAO

Spring Context

Spring core

拓展

Spring Boot:一个快速开发的脚手架

​ 基于SPringBoot可以快速的开发单个微服务

Spring Cloud

​ Spring Cloud 是基于SpringBoot实现的

以为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SPringMVC 承上启下的作用

Spring弊端:发展了太久,违背了原来的理念,配置十分繁琐.
IOC

之前开发步骤

1.UserDAO接口

2.UserDaompl实现类

3.UserService业务接口

4.UserServiceimpl业务实现类

之前的业务的客户需求可能会影响原来的代码,我们需要根据用户的需求修改源代码,如果程序代码量大,修改的成本会很大

使用set接口实现

private  UserDao  userdao
 
 public void setuserDao(UserDao userDao){
 this.userDao=uesrDao;
 }

之前,程序主动创建对象,控制权在程序员手上

使用set注入,程序员不在具有主动性,而是成为了被动接收对象

这种思想,从本质上解决了问题,程序员不用再创建对象,系统的耦合性大大降低,可以更加专注业务的实现。这是IOC的原型。

IOC本质

控制反转IOC是一种设计思想,DI是实现ioc的一种方法,没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象转移给第三方

控制反转是一种通过描述(xml或注解)并通过第三方去生产或获取特定对象的方式,在spring中实现控制反转的是ioc容器,其实现的方法是依赖注入
Hello Spring
实体类
package com.yuan.pojo;

public class Hello {
    private String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}
beans.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">
<!--使用spring来创建对象,在spring中这些都称为bean
bean=对象,一个bean等于new了一个对象
id相当于 HELLO hello=new Hello
property相当给hello设定了一个值
-->
<!--ref spring容器创建的对象
     value 具体的值,基本数据类型-->
<bean id="hello" class="com.yuan.pojo.Hello">
<property name="str" value="Spring"/>

</bean>
测试类
public class Mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Hello hello = (Hello) context.getBean("hello");
        System.out.println(hello);
    }
}
IOC创建对象的方式

使用无参构造创建对象

如果要使用有参构造,如下方式


    <bean id="user" class="www.yuan.pojo.User">
   第一种方法 <!--下标赋值法-->
    <constructor-arg index="0" value="袁伟java"/>
    </bean>
   第二种方法<!--参数类型,不建议使用-->    
   <constructor-arg type="java.lang.String" value="袁伟"/>
     </bean>
   第三种方法<!--直接通过参数来设值-->
   <constructor-arg name="name" value="袁伟"/>      
    </bean>
    </beans>
在配置文件加载的时候,容器中管理的对象就已经被初始化了,实例化的对象就只有那一个,去多少次,始终是那一个!
Spring配置
1.别名
<bean id="user" class="www.yuan.pojo.User">
        <constructor-arg name="name" value="袁伟"/>
    </bean>
    <alias name="user" alias="abc"/>
2.配置
<bean id="user" class="www.yuan.pojo.User">
id:bean的唯一标识符,也就是相当于我们学的对象名
class:bean对象所对应的权限定名:包名+类型
name:也是别名,可以去多个别名
3.import

import一般用于团队开发,可将多个配置文件,导入合并为一个

依赖注入
1.构造器注入
2.set方式注入

​ 依赖:bean对象的创建依赖于容器

​ 注入:bean对象中所有属性,由容器来注入

​ 【环境搭建】

复杂类型

package com.yuan.pojo;

public class Address {
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

测试对象

package com.yuan.pojo;

import java.util.*;

public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobby;
    private Map<String,String> card;
    private Set<String> games;
    private Properties info;
    private String wife;

beans

 <bean id="student" class="com.yuan.pojo.Student">
        <property name="name" value="袁伟"/>
    </bean>

测试

public class Mytest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) classPathXmlApplicationContext.getBean("student");
        System.out.println(student.getName());
    }
}

所有类型的注入方式

<bean id="address" class="com.yuan.pojo.Address"/>
    <bean id="student" class="com.yuan.pojo.Student">
        <!--普通注入-->
        <property name="name" value="袁伟"/>
        <!--bean注入,ref-->
        <property name="address" ref="address"/>
        <!--数组注入,ref-->
        <property name="books">
            <array>
                <value>西游记</value>
                <value>红楼梦</value>
                <value>三国演义</value>
                <value>水浒传</value>
            </array>
        </property>
       <!--LIst集合-->
        <property name="hobby">
            <list>
                <value>吉他</value>
                <value>游泳</value>
                <value>跑步</value>
            </list>
        </property>
        <!--map集合-->
        <property name="card">
            <map>
                <entry key="火" value="水"/>
            </map>
        </property>
        <!--set-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>DNF</value>
            </set>
        </property>
        <!--null-->
        <property name="wife">
            <null/>
        </property>
       <!--properties集合 值必须写在尖括号之间-->
        <property name="info">
            <props>
                <prop key="姓名">袁伟</prop>
                <prop key="城市">西安</prop>
            </props>
        </property>
    </bean>
3.拓展方式注入

​ 使用p命名和c命名注入

  <!--p命名注入可以直接注入属性的值-->
<bean id="user" class="com.yuan.pojo.User" p:name="袁伟" p:age="24"/>

    <!--c命名空间注入 可以通过构造器注入,construct-->
<bean id="user2" class="com.yuan.pojo.User" c:name="张峰" c:age="24"/>
</beans>

Bean的作用域

单例模式
<bean id="user2" class="com.yuan.pojo.User" c:name="张峰" c:age="24" scope="singleton"/>
原型模式:每次从容器中get的时候,都会产生一个新对象
<bean id="user2" class="com.yuan.pojo.User" c:name="张峰" c:age="24" scope="prototype"/>
其余的request,session,application这些只能在web开发应用

Bean的自动装配

自动装配是spring满足bean依赖一种方式

spring会在上下文自动寻找,并自动给bean装配属性

在spring中有三种装配方式

1.在xml中显示配置

2.在java中显示配置

3.隐式的自动配置bean

自动装配

方式一

<bean id="mao" class="com.yuan.pojo.cat"/>
    <bean id="gou" class="com.yuan.pojo.dog"/>
    <bean id="person" class="com.yuan.pojo.person" autowire="byName">
        <!--byName会自动在容器上下文中查找。和自己对象set方法后面的值对应的beanid-->
        <property name="name" value="袁伟"/>

方式二

<bean id="mao11" class="com.yuan.pojo.cat"/>
    <bean id="gou11" class="com.yuan.pojo.dog"/>
    <bean id="person" class="com.yuan.pojo.person" autowire="byType">
        <!--byType会自动在容器上下文查找,和自己对象属性类型相同的对应的bean-->
        <property name="name" value="袁伟"/>

byname,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性set方法的值一致

bytype,需要保证所有bean的class唯一,并且bean需要和自动注入的属性的类型一致

注解实现自动装配

jdk1.5支持的注解,spring2.5就支持注解

使用注解须知:

1.导入yueshu

2.配置注解的支持

<?xml version="1.0" encoding="UTF-8"?>
<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/>

</beans>

@Autowire

beans.xml

 <bean id="mao" class="com.yuan.pojo.cat"/>
    <bean id="gou" class="com.yuan.pojo.dog"/>
    <bean id="person" class="com.yuan.pojo.person">

实体类

public class person {
    @Autowired
   private dog gou;
    @Autowired
   private cat mao;
   private String name;
//@Autowire 也可以放在set方法上,在属性上时,也可以不要set方法

​ 如果@Autowire自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowire】完成的时候,我们可以使用@Qualifier(value=“xxx‘)去配置@AUtowire的使用,指定一个唯一的bean的注入

@Rescourse注解
public class people{
    @Resource(name="cat")
    private Cat cat;
    @Rescource
    private Dog dog;
}
//java注解

​ 小结

​ 都是用来自动装配,都可以放在字段上

​ @Autowire的默认方式是byType

​ @Rescource默认先通过byname,如果找不到名字,则通过bytype实现

使用注解开发

在spring4之后,要使用注解开发,必须保证aop的包导入了

使用注解需导入context约束,需要注解的支持

<?xml version="1.0" encoding="UTF-8"?>
<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/>

</beans>
属性注入
//等价于<bean id="user"  class="com.yuan.pojo.user"
@Component
public class User {
    public String name;

    public String getName() {
        return name;
    }
    //相当于<property name="name"  value="袁伟"
    @Value("袁伟")
    public void setName(String name) {
        this.name = name;
    }
}

衍生的注解

@component有几个衍生注解,在web开发中,会按照mvc三层架构分层

dao (@Repostory)

service(@service)

controller(@controller)

这几个衍生的注解功能都是一样的,都是代表将某个类注册到spring中,装配bean

使用java配置spring
//这个也会spring托管,注册到容器中,因为本来就是一个@component
//@Configuration 代表这是一个配置类,相当于之前的beans.xml
@Configuration
public class hello {
//注册一个bean,相当于之前的一个bean标签
    //方法的名字相当于bean的id
    //返回值,相当于class属性
    @Bean
    public User getUser(){
        return  new User();
    }
}
public class User {
    private String name;

    public String getName() {
        return name;
    }
@Value("袁伟")
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}
public class Mytest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(hello.class);
         User user = (User) annotationConfigApplicationContext.getBean("getUser");
        System.out.println(user.getName());
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值