注解 @Component及@Controller等,@Autowired,@Resource

注解:

对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 bean 实例。Spring 中使用注解, 需要在原有 Spring 运行环境基础上再做一些改变。 需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。

    <!--声明组件扫描器(component-scan),组件就是java对象
        base-package:指定注解在你的项目中的包名。
        component-scan工作方式: spring会扫描遍历base-package指定的包,
           把包中和子包中的所有类,找到类中的注解,按照注解的功能创建对象,或给属性赋值。

       加入了component-scan标签,配置文件的变化:
        1.加入一个新的约束文件spring-context.xsd
        2.给这个新的约束文件起个命名空间的名称
    -->

测试类如下:

package com.bjpowernode;

import com.bjpowernode.ba01.Student;
import com.bjpowernode.ba01.Teacher;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest01 {

    @Test
    public void test01(){
        String config="applicationContext-back.xml";
        ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
        //从容器中获取对象
        Student student = (Student) ctx.getBean("myStudent");

        System.out.println("student="+student);
    }

    @Test
    public void test02(){
        String config="applicationContext-back.xml";
        ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
        //从容器中获取对象

        Teacher teacher = (Teacher) ctx.getBean("teacher");
        teacher.setName("阿花");
        teacher.setAge(13);

        System.out.println(teacher);
    }
}

1. 注解的三种方式(不能同时用三种)

    指定多个包的三种方式
    第一种方式:使用多次组件扫描器,指定不同的包
    <context:component-scan base-package="com.bjpowernode.ba01"/>
    <context:component-scan base-package="com.bjpowernode.ba02"/>

    <!--第二种方式:使用分隔符(;或,)分隔多个包名-->
    <context:component-scan base-package="com.bjpowernode.ba01;com.bjpowernode.ba02" />

    <!--第三种方式:指定父包-->
    <context:component-scan base-package="com.bjpowernode" />

2. 定义 Bean 的注解@Component(掌握)

需要在类上使用注解@Component,该注解的 value 属性用于指定该 bean 的 id 值。 举例:di01

其中test.properties文件内容如下:

然后再applicationContext.xml中引入即可

另外,Spring 还提供了 3 个创建对象的注解:

➢ @Repository 用于对 DAO 实现类进行注解

➢ @Service 用于对 Service 实现类进行注解

➢ @Controller 用于对 Controller 实现类进行注解

这三个注解与

@Component 都可以创建对象,但这三个注解还有其他的含义,@Service 创建业务层对象,业务层对象可以加入事务功能,

@Controller 注解创建的对象可以作为处 理器接收用户的请求。 @Repository,

@Service,

@Controller 是对@Component 注解的细化,标注不同层的对 象。即持久层对象,业务层对象,控制层对象。 @Component 不指定 value 属性,bean 的 id 是类名的首字母小写。

3.byType 自动注入@Autowired(掌握)

需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配 Bean 的方式。 使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加 到 setter 上。

package com.bjpowernode.ba03;

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


@Component("myStudent")
public class Student {

    /**
     * @Value: 简单类型的属性赋值
     *   属性: value 是String类型的,表示简单类型的属性值
     *   位置: 1.在属性定义的上面,无需set方法,推荐使用。
     *         2.在set方法的上面
     */
    @Value("李四" )
    private String name;
    private Integer age;

    /**
     * 引用类型
     * @Autowired: spring框架提供的注解,实现引用类型的赋值。
     * spring中通过注解给引用类型赋值,使用的是自动注入原理 ,支持byName, byType
     * @Autowired:默认使用的是byType自动注入。
     *
     *  位置:1)在属性定义的上面,无需set方法, 推荐使用
     *       2)在set方法的上面
     */
    @Autowired
    private School school;

    public Student() {
        System.out.println("==student无参数构造方法===");
    }

    public void setName(String name) {
        this.name = name;
    }
    @Value("30")
    public void setAge(Integer age) {
        System.out.println("setAge:"+age);
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}

测试类如下:

package com.bjpowernode;

import com.bjpowernode.ba03.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest03 {

    @Test
    public void test01(){
        String config="applicationContext.xml";
        ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
        //从容器中获取对象
        Student student = (Student) ctx.getBean("myStudent");

        System.out.println("student="+student);
    }
}

4.byName 自动注入@Autowired 与@Qualifier(掌握)

1.在属性上面加入@Autowired
2.在属性上面加入@Qualifier(value="bean的id") :表示使用指定名称的bean完成赋值。

package com.bjpowernode.ba04;

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


@Component("myStudent")
public class Student {

    @Value("李四" )
    private String name;
    private Integer age;

    /**
     * 引用类型
     * @Autowired: spring框架提供的注解,实现引用类型的赋值。
     * spring中通过注解给引用类型赋值,使用的是自动注入原理 ,支持byName, byType
     * @Autowired:默认使用的是byType自动注入。
     *
     *  位置:1)在属性定义的上面,无需set方法, 推荐使用
     *       2)在set方法的上面
     *
     *  如果要使用byName方式,需要做的是:
     *  1.在属性上面加入@Autowired
     *  2.在属性上面加入@Qualifier(value="bean的id") :表示使用指定名称的bean完成赋值。
     */

    //byName自动注入
    @Autowired
    @Qualifier("mySchool")
    private School school;

    public Student() {
        System.out.println("==student无参数构造方法===");
    }

    public void setName(String name) {
        this.name = name;
    }
    @Value("30")
    public void setAge(Integer age) {
        System.out.println("setAge:"+age);
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}

测试类如下:

package com.bjpowernode;

import com.bjpowernode.ba04.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest04 {

    @Test
    public void test01(){
        String config="applicationContext.xml";
        ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
        //从容器中获取对象
        Student student = (Student) ctx.getBean("myStudent");

        System.out.println("student="+student);
    }
}
  • @Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运 行。若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。

    package com.bjpowernode.ba05;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    
    @Component("myStudent")
    public class Student {
    
        @Value("李四" )
        private String name;
        private Integer age;
    
        /**
         * 引用类型
         * @Autowired: spring框架提供的注解,实现引用类型的赋值。
         * spring中通过注解给引用类型赋值,使用的是自动注入原理 ,支持byName, byType
         * @Autowired:默认使用的是byType自动注入。
         *
         *   属性:required ,是一个boolean类型的,默认true
         *        required=true:表示引用类型赋值失败,程序报错,并终止执行。
         *        required=false:引用类型如果赋值失败, 程序正常执行,引用类型是null
         *
         *  位置:1)在属性定义的上面,无需set方法, 推荐使用
         *       2)在set方法的上面
         *
         *  如果要使用byName方式,需要做的是:
         *  1.在属性上面加入@Autowired
         *  2.在属性上面加入@Qualifier(value="bean的id") :表示使用指定名称的bean完成赋值。
         */
    
        //byName自动注入
        @Autowired(required = false)
        @Qualifier("mySchool-1")
        private School school;
    
        public Student() {
            System.out.println("==student无参数构造方法===");
        }
    
        public void setName(String name) {
            this.name = name;
        }
        @Value("30")
        public void setAge(Integer age) {
            System.out.println("setAge:"+age);
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", school=" + school +
                    '}';
        }
    }
    

    测试类如下:

    package com.bjpowernode;
    
    import com.bjpowernode.ba05.Student;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest05 {
    
        @Test
        public void test01(){
            String config="applicationContext.xml";
            ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
            //从容器中获取对象
            Student student = (Student) ctx.getBean("myStudent");
    
            System.out.println("student="+student);
        }
    }
    
    

    5.JDK 注解@Resource 自动注入(掌握)(注意是java提供的注解)

    Spring提供了对 jdk中@Resource注解的支持。@Resource 注解既可以按名称匹配Bean, 也可以按类型匹配 Bean。默认是按名称注入。使用该注解,要求 JDK 必须是 6 及以上版本。 @Resource 可在属性上,也可在 set 方法上。

@Resource 注解使用方法

* 引用类型
* @Resource: 来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值
*            使用的也是自动注入原理,支持byName, byType .默认是byName
*  位置: 1.在属性定义的上面,无需set方法,推荐使用。
*        2.在set方法的上面
package com.bjpowernode.ba06;

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

import javax.annotation.Resource;


@Component("myStudent")
public class Student {

    @Value("李四" )
    private String name;
    private Integer age;

    /**
     * 引用类型
     * @Resource: 来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值
     *            使用的也是自动注入原理,支持byName, byType .默认是byName
     *  位置: 1.在属性定义的上面,无需set方法,推荐使用。
     *        2.在set方法的上面
     */
    //默认是byName: 先使用byName自动注入,如果byName赋值失败,再使用byType
    @Resource
    private School school;

    public Student() {
        System.out.println("==student无参数构造方法===");
    }

    public void setName(String name) {
        this.name = name;
    }
    @Value("30")
    public void setAge(Integer age) {
        System.out.println("setAge:"+age);
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}

测试结果如下:

@Resource只是使用byName 属性

@Resource只使用byName方式,需要增加一个属性 name
package com.bjpowernode.ba07;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;


@Component("myStudent")
public class Student {

    @Value("李四" )
    private String name;
    private Integer age;

    /**
     * 引用类型
     * @Resource: 来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值
     *            使用的也是自动注入原理,支持byName, byType .默认是byName
     *  位置: 1.在属性定义的上面,无需set方法,推荐使用。
     *        2.在set方法的上面
     *
     * @Resource只使用byName方式,需要增加一个属性 name
     * name的值是bean的id(名称)
     */
    //只使用byName
    @Resource(name = "mySchool")
    private School school;

    public Student() {
        System.out.println("==student无参数构造方法===");
    }

    public void setName(String name) {
        this.name = name;
    }
    @Value("30")
    public void setAge(Integer age) {
        System.out.println("setAge:"+age);
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", school=" + school +
                '}';
    }
}
posted @   a-tao必须奥利给  阅读(93)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示