Spring

neweastsun 2019-10-29

Spring 框架:
    前无古人,后无来者。它可以包容其他的一切框架。
    a. 什么是Spring框架:
        它是用于简化J2EE业务层开发的轻量级技术框架,他的核心是IOC和AOP
        AOP:编程思想:面向对象: OOP
                           过程
                           服务:   分布式架构:SOA
                           切面的编程: AOP
    b. 编码体验Spring 的强大之处:
        作用:可以把普通的JavaBean魔术般的变为ejb
        对象实例化的不同之处
        
    c. 引入Spring框架
        Spring.jar : spring1.0-Spring5.0 (屹立不倒,而且越来越牛)
    d. 使用的Spring框架(容器)来构建对象:
        观察:实例化武器Weapon   实例化骑士Knight
        利用Spring框架来实例化这两个对象
        配置 xml/annocation:以前Spring框架都是利用XML来配置
        ,但是现在来看还是标注。并存的,看的懂,其实用xml配置更加灵活
        ,清晰,但是他比较繁琐,而标注比较简单
        beans.xml --- src/main/resources
    e. 在配置文件中配置你需要实例化的JavaBean
            Weapon      Knight
    f. 调用代码实例化Bean    
    
 原理: 工厂设计模式  反射机制
    a.构建BeanFactory
    ApplicationContext:其实就是那个工厂,他是创建Bean的工厂类
    所以Spring框架利用了工厂设计模式,先构造出工厂类,然后工厂来实例化
    他所管理的Bean。
    b. 你要告诉这个工厂我要实例化哪些Bean传一个字符串来告诉工厂实例化的类
        Spring把要实例化的Bean写到了配置文件中,
        然后利用XML的解析技术拿到要实例化累的相关信息,然后实例化相应的Bean
    c. 类只要能参数化了,那么就可以把他写道配置文件,
        然后就可以利用反射技术进行实例化Class.forName("类名")
结论:Spring是个大容器(工厂) 他去实例化你想要的Bean,也就是说你把Bean的生命周期纳入到Spring容器中去管理,
        不是我们直接构造出来的,这种技术就交Spring的IOC技术。
        IOC技术: 控制反转,也叫(依赖注入),他们说的一回事。
        控制反转:Bean的生命周期不受你控制,而是交给Spring容器管理。
优势: 1. 解耦,完全可以面向接口编程
            在代码中完全不用体现具体的实现类
        2. 类配置在配置文件中,方便修改维护
        Spring容器对Bean的管理,默认是单例的。
        Spring框架用到那些设计模式:工厂模式  单例模式 代理设计模式
    Spring框架如何利用IOC
        (1). 实现了控制反转,Spring容器能帮我们实例化对象,但是并没有做到DI(依赖注入)//为我们提供依赖注入。
    
配置Spring
    xml来配置Bean,利用Spring容器来例化Bean(IOC)
    Spring(4.0),Spring支持用标注的形式来配置
    如何利用标注来实现Spring框架的IOC?
    (1). 利用@Componet标注来注解你要纳入到Spring容器管理的类
    (2). 写个配置类,要告诉Spring从哪些地方来找这些Bean
    
    1. @Component 标注注解组件
    2. @Configuration
       @ComponentScan("day")    注明组件的位置,配置类相当于bean.xml配置文件
       @Autowired   如果Spring容器检测到Weapon类的实例,就会自动注入进来
       @Qualifier("axe")//-- 明确指定这个Bean
    3. Spring容器获取Bean

使用XML构建Spring

1.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">
    <!-- 武器Bean类 -->
   <bean id="weapon" class="day01.Axe"></bean>
    骑士Bean类
    <bean id="knight" class="day01.Knight">
        骑士Bean的武器属性
            name="weapon" 的值一定要和Knight类的属性值一样
            ref="weapon" 的值一定要和你配置的武器类Bean 的ID 一样
        
        <property name="weapon" ref="weapon"></property>
    </bean> 
    
</beans>

 2.Weapon.java

import org.springframework.stereotype.Component;

/**
 * 武器类(接口)
 * @author 
 *
 */
public interface Weapon {
    void fire();
}
//-- 斧头

class Axe implements Weapon{

    @Override
    public void fire() {
        System.out.println("砍两下.....");
    }
    
}

class Gun implements Weapon{
    @Override
    public void fire() {
        System.out.println("枪.....");
    }
}

3.Knight.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * 骑士类
 * @author 儿子
 *
 */

public class Knight {

    private Weapon weapon;
    
    public Knight() {}
    public Knight(Weapon weapon) {
        this.weapon = weapon;
    }
    
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
    
    public void attack() {
        weapon.fire();
    }
    
    
}

4.invoker.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * 调用者
 * 
 */
public class Invoker {
    public static void main(String[] args) {
        /* 以下的代码是我们传统的构造Bean的方式
        //-- 1. 武器
        Weapon weapon = new Axe();
        //-- 2. 骑士
        Knight knight = new Knight(weapon);
        //-- 3. 骑士发起攻击
        knight.attack();
        //-- 4. 换武器:
           knight.setWeapon(new Gun());
        knight.attack();
        */
        
        //-- 利用Spring框架来构建Bean对象
        //-- 1. 构造Spring容器对象(利用xml文件的配置)
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    //-- 2. 通过Spring容器来获取想要的Bean
    Knight knight = (Knight)ctx.getBean("knight");
    //-- 3. 骑士发起攻击
    knight.attack();    
    
    }
}

使用注解构建Spring

 1.Weapon.java

import org.springframework.stereotype.Component;

/**
 * 武器类(接口)
 * @author 
 *
 */
public interface Weapon {
    void fire();
}
//-- 斧头
@Component("axe")
class Axe implements Weapon{

    @Override
    public void fire() {
        System.out.println("砍两下.....");
    }
    
}
@Component("gun")
class Gun implements Weapon{
    @Override
    public void fire() {
        System.out.println("枪.....");
    }
}

 2.Knight.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * 骑士类
 * @author 儿子
 *
 */
@Component("knight")
public class Knight {
    @Autowired //- 如果Spring容器检测到Weapon类的实例,就会自动注入进来
    @Qualifier("axe")//-- 明确指定这个Bean
    private Weapon weapon;
    
    public Knight() {}
    public Knight(Weapon weapon) {
        this.weapon = weapon;
    }
    
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
    
    public void attack() {
        weapon.fire();
    }
    
    
}

 3.Weapon.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * Spring 容器的配置类,来代替那个Bean.xml文件
 * 1. 类上面使用@Component来注解
 * 2. 在配置类中使用@Bean 标注来注解你要实例化的类
 * @author 
 *
 */
@Configuration
@ComponentScan("day01")    //-- 告诉Spring从哪个包下寻找Component或者Bean
public class BaseConfiguration {
    /*@Bean("a")
    public String A(){        //- 类似于@Component标注
        return "a";
    }
    
    @Bean("foo")
    public Foo foo() {
        return new Foo();
    }*/
}

 4.Invoker.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * 调用者
 * 
 */
public class Invoker {
    public static void main(String[] args) {
        /* 以下的代码是我们传统的构造Bean的方式
        //-- 1. 武器
        Weapon weapon = new Axe();
        //-- 2. 骑士
        Knight knight = new Knight(weapon);
        //-- 3. 骑士发起攻击
        knight.attack();
        //-- 4. 换武器:
        knight.setWeapon(new Gun());
        knight.attack();
        */
        
    
        //-- 1.构造Spring容器
        ApplicationContext ctx = 
                new AnnotationConfigApplicationContext(BaseConfiguration.class);
        //-- 2. 获取Bean
        
        Knight knight = (Knight)ctx.getBean("knight");
//        System.out.println(ctx.toString());
        knight.attack();
        
//        Axe axe = (Axe)ctx.getBean("axe");
//        System.out.println(axe);
//        axe.fire();
    }
}

相关推荐