SpringIoc

2 篇文章 0 订阅

Ioc

  1. 代码的依赖关系被Ioc集中管理起来,清晰明了
  2. 每个类只需要关心自己的业务逻辑
  3. 修改依赖关系很容易
通过一个Ioc容器感受一下什么是IoC
package car;

public interface Car {
    public void start();
    public void turnLeft();
    public void turnRight();
    public void stop();
}
package car;

public class Audi implements Car{
    @Override
    public void start() {
        System.out.println("Audi start");
    }

    @Override
    public void turnLeft() {
        System.out.println("Audi turnLeft");

    }

    @Override
    public void turnRight() {
        System.out.println("Audi turnRight");

    }

    @Override
    public void stop() {
        System.out.println("Audi stop");

    }
}
package car;

public class Buick implements Car{

    @Override
    public void start() {
        System.out.println("Buick start");
    }

    @Override
    public void turnLeft() {
        System.out.println("Buick turnLeft");

    }

    @Override
    public void turnRight() {
        System.out.println("Buick turnRight");

    }

    @Override
    public void stop() {
        System.out.println("Buick stop");

    }
}
package humen;

public interface Humen {
    public void goHome();
}
package humen;

import car.Car;

public abstract class HumenWithCar implements Humen {
    protected Car car;

    public HumenWithCar (Car car) {
         this.car = car;
    }
    public abstract void goHome();
}
package humen;

import car.Car;

public class ZhangSan extends HumenWithCar{

    public  ZhangSan(Car car){
        super(car);
    }
    @Override
    public void goHome() {
        car.start();
        car.turnLeft();
        car.turnRight();
        car.stop();
    }
}
package humen;

import car.Car;

public class LiSi extends HumenWithCar{
    public LiSi (Car car){
        super(car);
    }
    @Override
    public void goHome() {
        car.start();
        car.stop();
    }
}
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/*
    实例化bean
    保存bean
    提供bean
    每一个bean要产生一个唯一的id与之对应
* */
public class IocContainer {
    private Map<String , Object> beans = new ConcurrentHashMap<>();
/*
根据BeanId获取Bean
 */
    public Object getBean(String beanId) {
        return beans.get(beanId);
    }
//委托IOC容器创建一个bean
//clazz 要创建的bean 的class , paramBeanIds 要创建的bean的class的构造方法所需要的参数Id们
    public void setBean(Class<?> clazz, String beanId , String... paramBeanIds) {
//        1.组装构造方法的参数值
        Object[] paramValues = new Object[paramBeanIds.length];
        for (int i = 0; i < paramBeanIds.length; i++) {
            paramValues[i] = beans.get(paramBeanIds[i]);
        }
//        2.调用构造方法实例化bean
        Object bean = null;
        for (Constructor<?> constructor:
        clazz.getConstructors()) {
            try {
                bean = constructor.newInstance(paramValues);
            } catch (InstantiationException e) {
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }
        }
        if (bean == null){
            throw  new RuntimeException("找不到合适的方法实例化bean");
        }
//        3.将实例化的bean 放入beans
        beans.put(beanId , bean);
    }
}
import car.Audi;
import car.Buick;
import humen.Humen;
import humen.ZhangSan;
import org.junit.Before;
import org.junit.Test;

public class IocTest {
    private  IocContainer iocContainer = new IocContainer();
    @Before
    public void before() {
        iocContainer.setBean(Audi.class , "audi");
        iocContainer.setBean(Buick.class , "buick");
        iocContainer.setBean(ZhangSan.class , "zhangsan","audi");
        iocContainer.setBean(ZhangSan.class , "lisi","buick");
    }
    @Test
    public void test(){
        Humen zhangSan = (Humen) iocContainer.getBean("zhangsan");
        zhangSan.goHome();
        Humen liSi = (Humen) iocContainer.getBean("lisi");
        liSi.goHome();
    }
}
Spring IOC 实例化Bean

默认构造方法实例化Bean

<bean id="bean1" name="bean1_1" class="lesson2.Bean1"></bean>
    <alias name="bean1" alias="bean12"></alias>
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Bean1 bean1 = context.getBean("bean1" , Bean1.class);
        System.out.println("bean1 = " + bean1)

通过静态工厂方法实例化Bean

<bean class="lesson2.Bean2Factory" factory-method="getBean2" id="bean2"></bean>
 Bean2 bean2 = context.getBean("bean2" , Bean2.class);
        System.out.println("Bean2 = " +bean2);

通过实例工厂方法实例化Bean

  <bean class="lesson2.Bean3Factory" id="bean3Factory"></bean>
    <bean class="lesson2.Bean3" factory-bean="bean3Factory" factory-method="getBean3"
          id="bean3"></bean>
 Bean3 bean3 = context.getBean("bean3" , Bean3.class);
        System.out.println("bean3 + " +bean3);

整个demo的例子

<?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-2.5.xsd">


    <bean id="bean" class="lesson1.Bean"></bean>

    <bean id="bean1" name="bean1_1" class="lesson2.Bean1"></bean>
    <alias name="bean1" alias="bean12"></alias>
    <bean class="lesson2.Bean2Factory" factory-method="getBean2" id="bean2"></bean>

    <bean class="lesson2.Bean3Factory" id="bean3Factory"></bean>
    <bean class="lesson2.Bean3" factory-bean="bean3Factory" factory-method="getBean3"
          id="bean3"></bean>
</beans>

package lesson2;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Bean1Test {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Bean1 bean1 = context.getBean("bean1" , Bean1.class);
        System.out.println("bean1 = " + bean1);

        Bean2 bean2 = context.getBean("bean2" , Bean2.class);
        System.out.println("Bean2 = " +bean2);
        Bean3 bean3 = context.getBean("bean3" , Bean3.class);
        System.out.println("bean3 + " +bean3);

        Bean1 bean1_1 = context.getBean("bean1_1" , Bean1.class);
        System.out.println("bean1_1 = " + bean1_1);
        Bean1 bean12 = context.getBean("bean12" , Bean1.class);
        System.out.println("bean12 = " + bean12 );
    }
}

package lesson2;

public class Bean1 {
    public Bean1 (){
        System.out.println("bean1");
    }
}

package lesson2;

public class Bean2 {
    public Bean2() {
        System.out.println("Bean.Bean2");
    }
}

package lesson2;

public class Bean2Factory {
    public static Bean2 getBean2(){
        return new Bean2();
    }
}
package lesson2;

public class Bean3 {
    public Bean3() {
        System.out.println("Bean2 hh");
    }
}
package lesson2;

public class Bean3Factory {
    public Bean3 getBean3() {
        return new Bean3();
    }
}

注入Bean


通过构造方法注入Bean
    <bean class="lesson3.AnotherBean" id="anotherBean"></bean>
    <bean class="lesson3.Bean" id="bean4">
<!--        index 标识是构造方法的第几个参数 value , ref 对参数赋值 value简单类型 , ref复杂类型-->
<!--        index name type 三个三个参数 唯一能够指示那个参数就可以-->
ref映射的是bean的id
        <constructor-arg index="0"
                         type="lesson3.AnotherBean"
                         ref="anotherBean"></constructor-arg>
        <constructor-arg index="1" type="java.lang.String" value="zzp"></constructor-arg>
    

<!--set方法注入-->

        <property name="anotherBean1" ref="anotherBean"></property>
        <property name="string1" value="zzp出现"></property>
    </bean>
通过set方法注入Bean
    <bean class="lesson3.AnotherBean" id="anotherBean"></bean>
    <bean class="lesson3.Bean" id="bean4">
<!--set方法注入-->

        <property name="anotherBean1" ref="anotherBean"></property>
        <property name="string1" value="zzp出现"></property>
    </bean>
以上俩种的简便写法
<!--    简便写法-->
<!--    <bean class="lesson3.Bean" id="bean"-->
<!--          c:anotherBean-ref="anotherBean" c:string="简便写法"-->
<!--    p:anotherBean1-ref="anotherBean"-->
<!--    p:string1="zzp简便写法"></bean>-->
集合类Bean的注入
<?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:c="http://www.springframework.org/schema/c"
       xmlns:p = "http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">




<!--    lesson3-->

    <bean class="lesson3.AnotherBean" id="anotherBean"></bean>
    <bean class="lesson3.Bean" id="bean">
<!--        index 标识是构造方法的第几个参数 value , ref 对参数赋值 value简单类型 , ref复杂类型-->
<!--        index name type 三个三个参数 唯一能够指示那个参数就可以-->
        <constructor-arg index="0"
                         type="lesson3.AnotherBean"
                         ref="anotherBean"></constructor-arg>
        <constructor-arg index="1" type="java.lang.String" value="zzp"></constructor-arg>

        <property name="anotherBean1" ref="anotherBean"></property>
        <property name="string1" value="zzp"></property>

        <property name="stringList">
            <list>
                <value>aaaa</value>
                <value>bbbb</value>
            </list>
        </property>
        <property name="anotherBeanList">
            <list>
                <ref bean="anotherBean"></ref>
                <ref bean="anotherBean"></ref>
            </list>
        </property>
        <property name="stringSet">
            <set>
                <value>aaaa</value>
                <value>bbbb</value>
            </set>
        </property>
        <property name="anotherBeanSet">
            <set>
                <ref bean="anotherBean"></ref>
                <ref bean="anotherBean"></ref>
            </set>
        </property>
        <property name="stringStringMap">
            <map>
                <entry key="ccc" value="dddd"></entry>
                <entry key="eee" value="ffff"></entry>
            </map>
        </property>
        <property name="anotherBeanMap">
            <map>
                <entry key-ref="anotherBean" value-ref="anotherBean"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="aaaaa">bbbbb</prop>
            </props>
        </property>
    </bean>




<!--    lesson3-->

</beans>
null值的注入
        <property name="anotherBean2">
            <null></null>
        </property>

Bean 作用域

<?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:c="http://www.springframework.org/schema/c"
       xmlns:p = "http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean class="lesson4.Bean2" id="bean2" scope="singleton"></bean>
    <bean id="bean1" class="lesson4.Bean1">
        <property name="bean2" ref="bean2"></property>
    </bean>
</beans>
Singleton作用域

同一个上下文的环境是产生一个单例,不同的上下文环境产生不同的单例

package lesson4;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Lesson4Test {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("lesson4.xml");
        Bean2 bean2_1 = context.getBean("bean2" , Bean2.class);
        System.out.println("bean2_1 = " + bean2_1);
        Bean2 bean2_2 = context.getBean("bean2" , Bean2.class);
        System.out.println("bean2_2 = " + bean2_2);
        Bean1 bean1 = context.getBean("bean1" , Bean1.class);
        System.out.println("bean1" + bean1);
        ApplicationContext context1 = new ClassPathXmlApplicationContext("lesson4.xml");
        Bean2 bean2_3 = context1.getBean("bean2" , Bean2.class);
        System.out.println("bean2_1 = " + bean2_1);
        Bean2 bean2_4 = context1.getBean("bean2" , Bean2.class);
        System.out.println("bean2_2 = " + bean2_2);
    }
}
prototype 作用域
package lesson4;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Lesson4Test {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("lesson4.xml");
        Bean2 bean2_1 = context.getBean("bean2" , Bean2.class);
        System.out.println("bean2_1 = " + bean2_1);
        Bean2 bean2_2 = context.getBean("bean2" , Bean2.class);
        System.out.println("bean2_2 = " + bean2_2);
        Bean1 bean1 = context.getBean("bean1" , Bean1.class);
        System.out.println("bean1" + bean1);
//        ApplicationContext context1 = new ClassPathXmlApplicationContext("lesson4.xml");
//        Bean2 bean2_3 = context1.getBean("bean2" , Bean2.class);
//        System.out.println("bean2_1 = " + bean2_1);
//        Bean2 bean2_4 = context1.getBean("bean2" , Bean2.class);
//        System.out.println("bean2_2 = " + bean2_2);
    }
}

Web 环境作用域
自定义作用域
Bean 懒加载
<?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:c="http://www.springframework.org/schema/c"
       xmlns:p = "http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
        <bean class="lesson1.Bean" id="bean" scope="singleton"></bean>
</beans>
package lesson1;

public class Bean {
    public Bean() {
        System.out.println("Bean已经被创建" + true);
    }
}

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import lesson1.Bean;
public class Lesson1Test {
    @Test
    public  void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        System.out.println("context已经被创建");
        Bean bean = context.getBean("bean" , Bean.class);
        System.out.println("bean = " +bean);
    }
}

Bean已经被创建true
context已经被创建
bean = lesson1.Bean@59d016c9

singleton作用域在初始化时就已经将bean加载好了

其他作用域是不会做初始化时加载bean

 <bean class="lesson1.Bean" id="bean" scope="singleton" lazy-init="true"></bean>
 context已经被创建
Bean已经被创建true
bean = lesson1.Bean@794cb805

加上这个标签就变为了懒加载

如果所有bean 都需要懒加载 :在beans标签加default-lazy-init=“true”

bean 初始化及销毁
如果在Bean 实例化后执行一些逻辑 ,俩种方法
  1. 使用init-method
  2. Bean 实现InitializingBean接口
如果在Bean 销毁后执行一些逻辑 ,俩种方法
  1. 使用destory-method
  2. Bean 实现DisposableBean接口

单例模式的销毁在context销毁时销毁

package lesson1;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Bean implements InitializingBean , DisposableBean {
    public Bean() {
        System.out.println("Bean已经被创建" + true);
    }
    public  void onInit(){
        System.out.println("bean.onInit");
    }
    public  void onDestroy(){
        System.out.println("bean.onDestroy");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("bean.destroy");

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("bean.afterPropertiesSet");
    }
}
<?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:c="http://www.springframework.org/schema/c"
       xmlns:p = "http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
        <bean class="lesson1.Bean"
              init-method="onInit" destroy-method="onDestroy"
              id="bean" ></bean>

</beans>
package lesson1;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Bean implements InitializingBean , DisposableBean {
    public Bean() {
        System.out.println("Bean已经被创建" + true);
    }
    public  void onInit(){
        System.out.println("bean.onInit");
    }
    public  void onDestroy(){
        System.out.println("bean.onDestroy");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("bean.destroy");

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("bean.afterPropertiesSet");
    }
}
Bean 属性继承
<?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:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    <bean class="lesson2.ParentClass" abstract="true"//不需要实例化的Bean id="parentClass">
        <property name="attribute1" value="attribute1"></property>
        <property name="attribute2" value="attribute2"></property>
        <property name="attribute3" value="attribute3"></property>
    </bean>

    <bean class="lesson2.Class1" id="class1" parent="parentClass">
        <property name="attribute4" value="attribute4"></property>
        <property name="attribute5" value="attribute5"></property>
    </bean>
    <bean class="lesson2.Class2" id="class2" parent="parentClass">
        <property name="attribute7" value="attribute7"></property>
        <property name="attribute8" value="attribute8"></property>
    </bean>
</beans>
package lesson2;

public class ParentClass {
    private String attribute1;
    private String attribute2;
    private String attribute3;

    public String getAttribute3() {
        return attribute3;
    }

    public void setAttribute3(String attribute3) {
        this.attribute3 = attribute3;
    }

    public String getAttribute1() {
        return attribute1;
    }

    public void setAttribute1(String attribute1) {
        this.attribute1 = attribute1;
    }

    public String getAttribute2() {
        return attribute2;
    }

    public void setAttribute2(String attribute2) {
        this.attribute2 = attribute2;
    }
}

package lesson2;

public class Class1 extends ParentClass{
    private String attribute4;
    private String attribute5;

    public String getAttribute4() {
        return attribute4;
    }

    public void setAttribute4(String attribute4) {
        this.attribute4 = attribute4;
    }

    public String getAttribute5() {
        return attribute5;
    }

    public void setAttribute5(String attribute5) {
        this.attribute5 = attribute5;
    }

    @Override
    public String toString() {
        return "Class1{" +
                "attribute4='" + attribute4 + '\'' +
                "attribute1='" + getAttribute1() + '\'' +
                "attribute2='" + getAttribute2() + '\'' +
                "attribute3='" + getAttribute3() + '\'' +
                ", attribute5='" + attribute5 + '\'' +
                '}';
    }
}

package lesson2;

public class Class2 extends ParentClass{
    private String attribute7;
    private String attribute8;

    public String getAttribute7() {
        return attribute7;
    }

    public void setAttribute7(String attribute7) {
        this.attribute7 = attribute7;
    }

    public String getAttribute8() {
        return attribute8;
    }

    public void setAttribute8(String attribute8) {
        this.attribute8 = attribute8;
    }

    @Override
    public String toString() {
        return "Class2{" +
                "attribute7='" + attribute7 + '\'' +
                ", attribute8='" + attribute8 + '\'' +
                ", attribute1='" + getAttribute1() + '\'' +
                ", attribute2='" + getAttribute2() + '\'' +
                ", attribute3='" + getAttribute3() + '\'' +
                '}';
    }
}

Spring 注解的使用

@Component(value = "bean2") //被注解的将有IOC管理 ,id 为 类名的小写 , 通用型注解
@Controller:被标注在Controller层
@Service:被标注在Service
@Repository: 被标注在Dao层

bean的别名

package lesson;

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

import java.util.List;

@Component
public class MyBean {
    private AnotherBean anotherBean1;
    private AnotherBean anotherBean2;
    @Autowired
    private AnotherBean anotherBean3;
    private List<String> stringList;

    public List<String> getStringList() {
        return stringList;
    }
    @Autowired
    @Qualifier("StringList")
    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }


    public AnotherBean getAnotherBean1() {
        return anotherBean1;
    }
    @Autowired
    public void setAnotherBean1(AnotherBean anotherBean1) {
        this.anotherBean1 = anotherBean1;
    }

    public AnotherBean getAnotherBean2() {
        return anotherBean2;
    }
    @Autowired
    public void setAnotherBean2(AnotherBean anotherBean2) {
        this.anotherBean2 = anotherBean2;
    }


    @Autowired
    public MyBean(AnotherBean anotherBean1) {
        this.anotherBean1 = anotherBean1;
    }

    @Override
    public String toString() {
        return "MyBean{" +
                "anotherBean1=" + anotherBean1 +
                ", anotherBean2=" + anotherBean2 +
                ", anotherBean3=" + anotherBean3 +
                '}';
    }
}

package lesson;

import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class AnotherBean {

}

package lesson;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import java.util.ArrayList;
import java.util.List;

@Configuration
@ComponentScan("lesson")
public class MyConfigruation {
    @Bean("StringList")
    public List<String> stringList(){
        List<String> list = new ArrayList<>();
        list.add("zzp");
        list.add("zzp1");
        return list;
    }
    @Bean
    @Order(34)
    public String string1(){
        return "222";
    }
    @Bean
    @Order(23)
    public String string2(){
        return "333";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

觅你风川间!!!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值