javaBean-IOC注入“进化史”(详解)

第一阶段:

IOC Bean创建对象的三种方式:

1. 无参构造器创建对象,默认。

  (1). 基本类型:value

<bean id="hello" class="com.edward.pojo.Hello">
   <property name="str" value="SpringStudy"></property>
</bean>

  (2). 引用类型:ref

<bean id="cat" class="com.edward.pojo.Cat"></bean>

<bean id="student" class="com.edward.pojo.Student">
   <property name="cat" ref="cat"></property>
</bean>

2.  有参构造器创建对象,有以下3种:

<!-- 第一种,下标赋值 -->
<bean id="user" class="com.edward.pojo.User">
    <constructor-arg index="0" value="牧羊狼的狼">
</bean>


<!-- 第二种,通过类型创建,不建议使用!! -->
<bean id="user" class="com.edward.pojo.User">
    <constructor-arg type="java.lang.String" value="牧羊狼的狼">
</bean>


<!-- 第三种,直接通过参数名设置 -->
<bean id="user" class="com.edward.pojo.User">
    <constructor-arg name="name" value="牧羊狼的狼">
</bean>

3.  命名空间的方式注入:

<?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:p="http://www.springframework.org/chema/p"
       xmlns:c="http://www.springframework.org/chema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!-- p命名空间注入,可以直接注入属性的值:property -->
    <bean id="user" class="com.edward.pojo.User" p:name="牧羊狼" p:age="18">

    
    <!-- c命名空间注入,可以直接注入属性的值:constructor-args -->
    <!-- User类中要有构造器 -->
    <bean id="user" class="com.edward.pojo.User" c:name="牧羊狼" c:age="18">


第二阶段:

之前:需要<property>的 ref 引入实例化的对象

进化:直接用 autowire 属性自动引入

(1). byName:  会在容器上下文中查找,和自己对象set方法后面的值对应的beanid

<bean id="cat1" class="com.edward.pojo.Cat"></bean>

<bean id="student" class="com.edward.pojo.Student" autowire="byName">
</bean>

Student.java:

 (2). byType:  会在容器上下文中查找,和自己对象属性类型相同的bean

如下:name="cat",自己对象属性类型为cat,正好有class="xxxCat"的<bean>

<bean id="cat" class="com.edward.pojo.Cat"></bean>

<bean id="student" class="com.edward.pojo.Student" autowire="byType">
    <!-- <property name="cat" ref="cat"></property> -->
</bean>

MyTest.java:

public class MyTest {
    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = context.getBean("student", Student.class);
        student.getCat().shout();
    }
}

byType时, 被引用的bean的id可以不写,但是class必须全局唯一   !!!!!

成功:

失败:


第三阶段 :    注解自动装配

之前:在xml 文件中,autowire 属性注入引用类型

进化:在 Class 文件中,@Autowired @Qualifier @Resource 注解注入

@Autowired:通过 byType 的方式注入

 第一步:导入约束链接,添加 <context:annotation-config /> 配置;

<?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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <context:annotation-config />

    <bean id="school2" class="com.edward.pojo.School"></bean>
    <bean id="hello" class="com.edward.pojo.Hello"></bean>

</beans>

第二步:给Class文件中的对象属性添加 @Autowired注解 (也可以在set方法上使用);

setSchool 方法可以去掉不写 ! !

测试文件不改:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Hello hello = context.getBean("hello", Hello.class);
hello.getSchool().teach();

@Qualifier

如果xml文件中同一个类型的 bean 有两个或多个,这时@Autowired 既不能通过 byName 找到对应的 bean, 也不能通过 byType 找到,就需要用到  @Qualifier(value="xxx") 注解

beans.xml:

<context:annotation-config />

<bean id="school2" class="com.edward.pojo.School"></bean>
<bean id="school3" class="com.edward.pojo.School"></bean>

<bean id="hello" class="com.edward.pojo.Hello"></bean>

Hello.java:

@Resource

默认通过 byName 的方式注入,如果找不到名字,则通过 byType 实现,如果都找不到则报错。


第四阶段:     注解自动注册 bean

之前:注解实现了自动装配,但 xml 文件依然需要写 <bean>

进化:   扫描要自动装配的包,在 java 文件中通过 @Component 给Class注册 <bean>

beans.xml:

<context:component-scan base-package="com.edward.pojo"></context:component-scan>
<context:annotation-config></context:annotation-config>

Student.java:

Cat.java:

测试文件不变:

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = context.getBean("student", Student.class);
        student.getCat().shout();
    }
}

@Value

使用了 @component 后,通过 @Value 直接给属性赋值

MyTest:

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

由 @Component 衍生的注解:

@Repository  【DAO层】

@Service        【Service层】

@Controller   【controller层】

这三个注解和 @Component 的功能都是一样的,都是代表将某个类注册到Spring中,装配Bean


第五阶段:       javaConfig 配置文件

之前:XML文件配置 <context:annotation-config> 等实现注入

进化:完全不需要 XML 配置文件,全权交给 java 来做!

删掉resources目录下的xml文件

新建 myConfig.java 文件:

myConfig.java:

@Configuration
public class MyConfig {
    @Bean
    public Hello hello () { // 方法名相当于bean标签的id
        return new Hello(); // 要注入bean的对象
    }
}

Hello.java:

@Component
public class Hello {

    @Value(value = "edward123")
    private String name;

    public String getName() {
        return name;
    }
}

MyTest:   AnnotationConfigApplicationContext

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        Hello hello = context.getBean("hello", Hello.class);
        String name = hello.getName();
        System.out.println(name);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值