spring的IOC,控制反转

spring的IOC,控制反转

Ioc全称Inversion of Control,即“控制反转”,这是一种设计思想。对象创建的权利由Spring框架完成.由容器管理对象的生命周期.

入门案例:(xml配置文件的方式)

1.定义行为规范的接口Pet
package com.jt.demo1;

public interface Pet {
    void hello();
}
2.定义接口的实现类:Dog类
package com.jt.demo1;

public class Dog implements Pet {
    public Dog(){
        System.out.println("我是无参构造~~~");
    }

    @Override
    public void hello() {
        System.out.println("小狗汪汪汪~~~");
    }
}
3.在resources目录下配置xml文件spring.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">
    
		<!--
            1. IOC的机制管理Dog对象
            id: 对象的唯一标识符. 不能重复 见名知意 首字母小写
            class: 类路径
        -->
    <bean id="dog" class="com.jt.demo1.Dog"></bean>
</beans>
4.创建测试类User,查看程序运行效果
public class User {
    public static void main(String[] args) {
        ApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
        Dog dog = (Dog) app.getBean("dog");
        dog.hello();
    }
}

IOC机制的原理

容器的数据结构: K-V Map<K,V> key=bean中的ID, value=实例化的对象
程序执行过程:

  1. 指定配置文件的名称.
  2. 当Spring容器加载配置文件时.当按照顺序执行bean标签时,开始创建对象.
  3. Spring通过bean标签中的class属性获取类型的路径,之后通过反射机制,实例化对象(必须有无参构造)
  4. bean中的Id当做Map中的key, 将实例化的对象保存到Map中,当做value. 至此Spring容器启动成功!!!
  5. 当用户需要获取对象时,可以通过key/或者类型 获取对象.

spring注解开发(改造入门案例)

1.定义行为规范的接口Pet
package com.jt.demo1;

public interface Pet {
    void hello();
}
2.定义接口的实现类:Dog类
package com.jt.demo1;

public class Dog implements Pet {
    public Dog(){
        System.out.println("我是无参构造~~~");
    }

    @Override
    public void hello() {
        System.out.println("小狗汪汪汪~~~");
    }
}
3.定义配置类SpringConfig
package com.jt.demo4;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

@ComponentScan("com.jt.demo4") //包扫描注解,让Spring注解生效!!!
@Configuration //标识当前类是配置类
public class SpringConfig {
    //作用:和配置文件类似,管理对象
    /*
    IOC-写法
    1.@Bean 告诉Spring容器,当前方法的名称,为Map中的key
    返回值是Map中的value
    2.特殊用法:常规条件下,Spring通过反射实例化对象,也可以由用户自己创建
     */
    @Bean
    public Dog dog(){
        return new Dog();
    }
}
4.创建测试类User,查看程序运行效果
package com.jt.demo4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class User {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Dog dog = context.getBean(Dog.class);
        dog.hello();
    }
}

Spring管理对象 方式一:(@Bean)

Bean容器对象的生命周期方法

package com.jt.demo6;

/*
Day03
spring对象的生命周期
 */

/**定义User类*/
public class User {
    //1.对象创建,Bean创建对象自动调用
    public User(){
        System.out.println("用户对象创建成功");
    }

    //2.进行初始化
    @PostConstruct  //初始化注解
    public void init(){
        System.out.println("为属性赋值");
    }

    //3.进行业务调用,业务方法,用户手动调用
    public void hello(){
        System.out.println("我爱java");
    }

    //4.销毁方法
    @PreDestroy   //标记为销毁方法
    public void destroy(){
        System.out.println("调用销毁方法,释放资源");
    }
}


/**创建配置类*/
@Configuration  //标识配置类
public class SpringConfig {

    @Bean  //把对象控制权交给Bean
    public User user(){
        return new User();
    }
}

/**测试类*/
public class TestUser {
    public static void main(String[] args) {
        //ApplicationContext app1 = new AnnotationConfigApplicationContext(SpringConfig.class);
        AnnotationConfigApplicationContext app2 = new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = app2.getBean(User.class);
        //调用业务方法
        user.hello();
        //如果需要执行销毁方法,则需要先关闭容器对象
        //知识点:容器的接口,没有提供关闭容器的操作,需要调用实现类的关闭方法
        //设计思想:销毁动作是敏感行为,特殊处理,实现类中有关闭方法
        //app1.close();//报错,接口中没有关闭方法
        app2.close();//先调用销毁方法,然后关闭容器

    }
}

Spring管理对象 方式二:(@Component)

容器对象的生命周期方法

package com.jt.demo6;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/*spring自动为该注解标识的类,通过反射实例化对象,
交给spring容器管理,
key:类名首字母小写user
value:反射机制创建出来的对象
类似于@Bean注解

@Component/@Bean区别:
1.@component spring容器通过反射自动创建对象
  @Bean 是用户自己手动创建的对象
2.@component  是标识类的
  @Bean 标识配置类中的方法
3.@component 对象的Id是类名的首字母小写
  @Bean 对象的Id是方法名
*/
@Component
public class User {
    //1.对象创建,Bean创建对象自动调用
    public User(){
        System.out.println("用户对象创建成功");
    }

    //2.进行初始化
    @PostConstruct  //初始化注解
    public void init(){
        System.out.println("为属性赋值");
    }

    //3.进行业务调用,业务方法,用户手动调用
    public void hello(){
        System.out.println("我爱java");
    }

    //4.销毁方法
    @PreDestroy   //标记为销毁方法
    public void destroy(){
        System.out.println("调用销毁方法,释放资源");
    }
}


/**配置类*/
@Configuration  //标识配置类
@ComponentScan("com.jt.demo6")
public class SpringConfig {

}


/**测试类*/
public class TestUser {
    public static void main(String[] args) {
        ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = app.getBean(User.class);
        //调用业务方法
        user.hello();
    }
}

总结:Component和Bean都可以标识把对象交给spring容器管理
@Component/@Bean区别:
1.@component spring容器通过反射自动创建对象
@Bean 是用户自己手动创建的对象
2.@component 是标识类的
@Bean 标识配置类中的方法
3.@component 对象的Id是类名的首字母小写
@Bean 对象的Id是方法名

Spring中依赖注入

依赖注入就是将spring容器中管理对象,赋值给对象的属性
核心机制:如果需要使用依赖注入,则对象的属性必须有setXxx()方法

xml配置文件写法
(1)为普通属性赋值

1.定义类(类里必须有set方法)

package com.jt.demo7_di;

public class Person {
    //定义属性
    private Integer id;
    private String name;

    //依赖注入,为属性赋值,必须有set方法
    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 void sayHi(){
        System.out.println("你好:"+id+":"+name);
    }

}

2.在resources目录下配置xml文件spring_di.xml(依赖注入,通过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">

<!--  xml配置文件  为属性赋值 -->
    <bean id="person" class="com.jt.demo7_di.Person">
        <!-- 通过Bean的property属性为类的属性赋值 -->
        <property name="id" value="100"/>
        <property name="name" value="春节"/>
    </bean>
</beans>

3.创建测试类,查看程序运行效果

public class TestPerson {
    public static void main(String[] args) {
        String resource = "spring_di.xml";
        ApplicationContext app = new ClassPathXmlApplicationContext(resource);
        Person person = app.getBean(Person.class);
        person.sayHi();
    }
}
(2)spring为对象赋值

1.定义Person类(类里必须有set方法)

package com.jt.demo7_di;

public class Person {
    //定义属性
    private Integer id;
    private String name;
    private Car car;  //spring容器为属性赋值

    //依赖注入,为属性赋值,必须有set方法
    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    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 void sayHi(){
        System.out.println("你好:"+id+":"+name);
    }
    public void toGo(){
        car.go();
    }

}

2.在resources目录下配置xml文件spring_di.xml(依赖注入,通过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">

<!-- 1.让spring容器管理car -->
    <bean id="car" class="com.jt.demo7_di.Car"></bean>

<!--  2.xml配置文件,让spring管理Person,并且为属性赋值 -->
    <bean id="person" class="com.jt.demo7_di.Person">
<!-- 通过Bean的property属性为类的普通属性赋值 -->
        <property name="id" value="2100"/>
        <property name="name" value="春节111"/>
<!-- 3.如果将对象赋值给属性,使用ref属性
        ref:引用的id
		相当于把spring管理的car对象传给person类的car属性,
		实现松耦合-->
        <property name="car" ref="car"/>
    </bean>
</beans>

3.创建测试类,查看程序运行效果

package com.jt.demo7_di;

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

public class TestPerson {
    public static void main(String[] args) {
        String resource = "spring_di.xml";
        ApplicationContext app = new ClassPathXmlApplicationContext(resource);
        Person person = app.getBean(Person.class);
        person.sayHi();
        person.toGo();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值