Spring(3)

本文详细介绍了Spring框架中Bean的三种装配方式:基于XML的Bean装配,包括构造注入和设值注入;基于Annotation的Bean装配,使用了@Component、@Repository、@Service、@Controller等注解;以及自动装配,如byName、byType、constructor和autodetect模式。通过实例展示了各种装配方式的使用方法和区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         Bean的装配可以理解为依赖注入,Bean的装配方式也就是Bean的依赖注入方式。装配方式有三种:基于XML的Bean装配基于Annotation的Bean装配自动装配

1.Spring基于XML装配Bean

       Spring 基于 XML 的装配通常采用两种实现方式,即设值注入构造注入

在 Spring 实例化 Bean 的过程中,首先会调用默认的构造方法实例化 Bean 对象,然后通过 Java 的反射机制调用 setXxx() 方法进行属性的注入。因此,设值注入要求一个 Bean 的对应类必须满足以下两点要求

A.必须提供一个默认的无参构造方法。(当没有构造方法时,每个类默认都有一个无参)

B.必须为需要注入的属性提供对应的 setter 方法。

使用设值注入时,在 Spring 配置文件中,需要使用 <bean> 元素的子元素 <property> 元素为每个属性注入值。而使用构造注入时,在配置文件中,主要使用 <constructor-arg> 标签定义构造方法的参数,可以使用其 value 属性(或子元素)设置该参数的值

1.1构造注入

       构造函数注入:

       <?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 id="myclass" class="com.weiwei.spring.MyClass">

        <constructor-arg index="0" value="2"></constructor-arg>

        <constructor-arg index="1" value="2.3"></constructor-arg>

        <constructor-arg index="2" value="a"></constructor-arg>

        <constructor-arg index="3" value="true"></constructor-arg>

    </bean>

</beans>

public class MyClass {

    //基本数据类型

    private int intvalue;

    private double doubvalue;

    private  char charvalue;

    private Boolean boovalue;



    public MyClass(){



        }

    public MyClass(int intvalue, double doubvalue, char charvalue, Boolean boovalue) {

        this.intvalue = intvalue;

        this.doubvalue = doubvalue;

        this.charvalue = charvalue;

        this.boovalue = boovalue;

    }

    public int getIntvalue() {

        return intvalue;

    }



    public double getDoubvalue() {

        return doubvalue;

    }



    public char getCharvalue() {

        return charvalue;

    }



    public Boolean getBoovalue() {

        return boovalue;

    }

}



public class Test {

    public static void main(String[] args) {

       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        MyClass myclass = applicationContext.getBean("myclass", MyClass.class);

        System.out.println("intvalue===="+myclass.getIntvalue());

        System.out.println("doubvalue===="+myclass.getDoubvalue());

        System.out.println("charvalue===="+myclass.getCharvalue());

        System.out.println("boovalue===="+myclass.getBoovalue());

    }

}

输出:

intvalue====2

doubvalue====2.3

charvalue====a

boovalue====true

      

       基本数据类型构造函数注入演示到这,后面重点演示设置注入。

1.2 设值注入

package com.weiwei.spring.demo2;

import java.util.*;

public class MyClass {

    //基本数据类型

    private int intvalue;

    private double doubvalue;

    private  char charvalue;

    private Boolean boovalue;

    //引用数据类型

    private String strvalue;

    //Date类型

    private Date datevalue;

    //对象类型

    private  Student student;

    //String数组

    private  String[] strarray;

    //对象类型数组

    private Student[] stuarr;

    //String类型集合

    private List<String> strlist;

    //对象类型集合

    private List<Student> stulist;

    //String类型set集合

    private Set<String> strset;

    //对象类型set集合

    private Set<Student> stuset;

    //String类型map集合

    private Map<String,String> stringMap;

    //对象类型map集合

    private Map<String,Student> studentMap;

    //properties

    private Properties properties;





    //提供getter和setter方法

    public int getIntvalue() {

        return intvalue;

    }



    public void setIntvalue(int intvalue) {

        this.intvalue = intvalue;

    }



    public double getDoubvalue() {

        return doubvalue;

    }



    public void setDoubvalue(double doubvalue) {

        this.doubvalue = doubvalue;

    }



    public char getCharvalue() {

        return charvalue;

    }



    public void setCharvalue(char charvalue) {

        this.charvalue = charvalue;

    }



    public Boolean getBoovalue() {

        return boovalue;

    }



    public void setBoovalue(Boolean boovalue) {

        this.boovalue = boovalue;

    }

    public String getStrvalue() {

        return strvalue;

    }



    public void setStrvalue(String strvalue) {

        this.strvalue = strvalue;

    }



    public Date getDatevalue() {

        return datevalue;

    }



    public void setDatevalue(Date datevalue) {

        this.datevalue = datevalue;

    }



    public Student getStudent() {

        return student;

    }



    public void setStudent(Student student) {

        this.student = student;

    }



    public String[] getStrarray() {

        return strarray;

    }



    public void setStrarray(String[] strarray) {

        this.strarray = strarray;

    }



    public Student[] getStuarr() {

        return stuarr;

    }



    public void setStuarr(Student[] stuarr) {

        this.stuarr = stuarr;

    }



    public List<String> getStrlist() {

        return strlist;

    }



    public void setStrlist(List<String> strlist) {

        this.strlist = strlist;

    }



    public List<Student> getStulist() {

        return stulist;

    }



    public void setStulist(List<Student> stulist) {

        this.stulist = stulist;

    }



    public Set<String> getStrset() {

        return strset;

    }



    public void setStrset(Set<String> strset) {

        this.strset = strset;

    }



    public Set<Student> getStuset() {

        return stuset;

    }



    public void setStuset(Set<Student> stuset) {

        this.stuset = stuset;

    }



    public Map<String, String> getStringMap() {

        return stringMap;

    }



    public void setStringMap(Map<String, String> stringMap) {

        this.stringMap = stringMap;

    }



    public Map<String, Student> getStudentMap() {

        return studentMap;

    }



    public void setStudentMap(Map<String, Student> studentMap) {

        this.studentMap = studentMap;

    }



    public Properties getProperties() {

        return properties;

    }



    public void setProperties(Properties properties) {

        this.properties = properties;

    }

}
package com.weiwei.spring.demo2;



public class Student {

   private String stuaddress;

   private String stuname;



    public String getStuaddress() {

        return stuaddress;

    }



    public void setStuaddress(String stuaddress) {

        this.stuaddress = stuaddress;

    }



    public String getStuname() {

        return stuname;

    }



    public void setStuname(String stuname) {

        this.stuname = stuname;

    }

}

package com.weiwei.spring.demo2;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



import java.text.SimpleDateFormat;

import java.util.Map;

import java.util.Properties;

import java.util.Set;



public class Test {

    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        MyClass myclass = applicationContext.getBean("myclass", MyClass.class);

        System.out.println("-----------基本数据类型--------------");

        System.out.println("intvalue===="+myclass.getIntvalue());

        System.out.println("doubvalue===="+myclass.getDoubvalue());

        System.out.println("charvalue===="+myclass.getCharvalue());

        System.out.println("boovalue===="+myclass.getBoovalue());



        System.out.println("-----------引用数据类型--------------");

        System.out.println("strvalue===="+myclass.getStrvalue());

        System.out.println("datevalue===="+new SimpleDateFormat("yyyy-MM-dd").format(myclass.getDatevalue()));

        System.out.println("student===="+myclass.getStudent().getStuaddress()+myclass.getStudent().getStuname());

        System.out.println("-----------String类型数组--------------");

        for (String strarr:myclass.getStrarray()) {

            System.out.println(strarr);

        }

        System.out.println("-----------对象类型数组--------------");

        for (Student student:myclass.getStuarr()) {

            System.out.println(student.getStuname());

        }

        System.out.println("-----------String类型集合--------------");

        for (String str1: myclass.getStrlist()) {

            System.out.println(str1);

        }

        System.out.println("-----------对象类型集合--------------");

        for (Student stu: myclass.getStulist()) {

            System.out.println(stu.getStuname());

        }

        System.out.println("-----------String类型set集合--------------");

        for (String strset:myclass.getStrset()){

            System.out.println(strset);

        }

        System.out.println("-----------对象类型set集合--------------");

        for (Student stuset:myclass.getStuset()) {

            System.out.println(stuset.getStuname());

        }

        System.out.println("-----------String类型map集合--------------");

        for (Map.Entry<String,String> entry:myclass.getStringMap().entrySet()) {

            System.out.println(entry.getKey()+entry.getValue());

        }

        System.out.println("-----------对象map--------------");

        for (Map.Entry<String,Student> entry:myclass.getStudentMap().entrySet()) {

            System.out.println(entry.getKey()+entry.getValue().getStuaddress());

        }

        System.out.println("-----------properties--------------");

        Properties properties = myclass.getProperties();

        Set<String> stringSet = properties.stringPropertyNames();

        for (String name:stringSet) {

            System.out.println(name+"====="+properties.getProperty(name));

        }

    }

}

输出:

-----------基本数据类型--------------

intvalue====520

doubvalue====30.5

charvalue====a

boovalue====false

-----------引用数据类型--------------

strvalue====竞宝

datevalue====2022-03-03

student====西安劲爆

-----------String类型数组--------------

张三

李四

王五

-----------对象类型数组--------------

劲爆

搜索

-----------String类型集合--------------

java班

前端班

微信小程序

-----------对象类型集合--------------

劲爆

搜索

-----------String类型set集合--------------

set1

set2

set3

-----------对象类型set集合--------------

劲爆

搜索

-----------String类型map集合--------------

name张三

addrexs西安

work程序员

-----------对象map--------------

stu1西安

stu2重庆

-----------properties--------------

password=====123456

username=====root

2. Spring基于Annotation装配Bean

在 Spring 中,尽管使用 XML 配置文件可以实现 Bean 的装配工作,但如果应用中 Bean 的数量较多,会导致 XML 配置文件过于臃肿,从而给维护和升级带来一定的困难。
       Java 从 JDK 5.0 以后,提供了 Annotation(注解)功能,Spring 也提供了对 Annotation 技术的全面支持。

使用前需要在配置文件中配置:自动扫描包中的注解

<?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"

       xsi:schemaLocation="http://www.springframework.org/schema/beans

        http://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/context

        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置自动扫描包-->

    <context:component-scan base-package="com.wangxing.demo1"></context:component-scan>

</beans>

Spring3 中定义了一系列的 Annotation(注解),常用的注解如下。

2.1 Component

(1)@Component

可以使用此注解描述Spring中的Bean创建对象】,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次使用时只需将该注解标注在相应类上即可

       @Component--默认使用@Component创建的Bean类的名称,首字母小写

@Component(name)--指定的名称

//@Component

@Component("stud") public class StudentBean {

    public void testStudent(){

        System.out.println("Stduent的实例方法");

    }

}

public class Test {

    public static void main(String[] args) {

       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

       //StudentBean student = applicationContext.getBean("studentBean", StudentBean.class);

        StudentBean student = applicationContext.getBean("stud", StudentBean.class);

        student.testStudent();

    }

}

2.2 Repository

(2)@Repository

用于将数据访问层(DAO层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

@Repository--默认使用@Repository创建的Bean类的名称,首字母小写

@Repository(name)--指定的名称

/**

 * 数据访问层的操作类

 */

//@Component("studentDao")

@Repository("studentDaoImpl")

public class StudentDaoImpl {

    public  void  insertStudent(){

        System.out.println("数据访问层添加方法");

    }

}

2.3 Service

       (3) @Service

通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

@Service--默认使用@Service创建的Bean类的名称,首字母小写

@Service(name)--指定的名称       

/**

 * 业务访问层操作类

 */

//@Component("studentService")

@Service("studentServiceImpl")

public class StudentServiceImpl {

    //@Autowired

    @Resource

    private StudentDaoImpl studentDao;

    public void  apperndStudent(){

        System.out.println("业务访问层添加方法");

        studentDao.insertStudent();

    }

}

2.4 Controller

       (4) @Controller

通常作用在控制层(如 Struts2 的 Action/SpringMVC的控制器类),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

@Controller--默认使用@Controller创建的Bean类的名称,首字母小写

@Controller(name)--指定的名称

/**

 * 控制层操作类

 */

//@Component("studentController")

@Controller("studentController")

public class StudentController {

    //@Autowired

    @Resource

    private StudentServiceImpl studentService;

    public  void addStudent(){

        System.out.println("控制层添加方法");

        studentService.apperndStudent();

    }

}

2.5 Autowired

(5) @Autowired

默认按照 Bean 的类型进行装配依赖注入.

用于对 Bean 的属性变量属性的 Set 方法及构造函数进行标注,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配

<context:component-scan base-package="com.weiwei.springdemo4.demo2"/>

@Component

public class StudentBean {

    public String getString(){

        return "竞宝";

    }

}

@Component("per")

public class PersonBean {

    @Autowired

    // @Autowired可以把studentBean对象注入到person中

    public StudentBean studentBean;

    public  void  testPer(){

        System.out.println("person的实例方法-------"+studentBean.getString());

    }

}

public class Test {

    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        PersonBean per = applicationContext.getBean("per", PersonBean.class);

        per.testPer();

    }

}

2.6 Resource

(6) @Resource

其作用与 Autowired 一样。其区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 实例名称进行装配
    @Resource 中有两个重要属性:name 和 type。
       Spring 将 name 属性解析为 Bean 实例名称,type 属性解析为 Bean 实例类型。如果指定 name 属性,则按实例名称进行装配;如果指定 type 属性,则按 Bean 类型进行装配。
       如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常

@Component("student")

public class StudentBean {

    public String getString(){

        return "宝儿";

    }

}

@Component("per")

public class PersonBean {

@Resource

//   @Resource(name = "student")   如果指定name,就必须和创建好的对象的名称一样

//    @Resource(type = StudentBean.class)

    private StudentBean studentBean;

    public  void testPerson(){

        System.out.println(studentBean.getString());

    }

}

public class Test {

    public static void main(String[] args) {

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        PersonBean per = applicationContext.getBean("per", PersonBean.class);

        per.testPerson();

    }

}

@Autowired与@Resource有什么区别?

Autowired默认按照类型装配,而Resource默认按照实例名称装配,并且带有name属性和type属性,如果使用name属性,则必须按照实例名称装配,否则抛出异常,如果使用type属性,则必须按照类型装配,否则抛出异常,如果不使用属性,则先匹配实例名称,找不到再匹配类型,再找不到则抛出异常。

2.7 Qualifier

       (7)@Qualifier

与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。

@Component("stss")

public class StudentBean {

    public String getString(){

        return "竞宝";

    }

}

@Component("per")

public class PersonBean {

    @Autowired

    @Qualifier("stss")

    // @Autowired可以把studentBean对象注入到person中

    public StudentBean studentBean;

    public  void  testPer(){

        System.out.println("person的实例方法-------"+studentBean.getString());

    }

}

3.Spring自动装配Bean

除了使用 XML 和 Annotation 的方式装配 Bean 以外,还有一种常用的装配方式——自动装配。自动装配就是指 Spring 容器可以自动装配(autowire)相互协作的 Bean 之间的关联关系,将一个 Bean 注入其他 Bean 的 Property 中。
       要使用自动装配,就需要配置 <bean> 元素的 autowire 属性。autowire 属性有五个值,具体说明如表所示。

名称

说明

byName

根据 Property 的 name 自动装配,如果一个 Bean 的 name 和另一个 Bean 中的 Property 的 name 相同,则自动装配这个 Bean 到 Property 中。

byType

根据 Property 的数据类型(Type)自动装配,如果一个 Bean 的数据类型兼容另一个 Bean 中 Property 的数据类型,则自动装配。

constructor

根据构造方法的参数的数据类型,进行 byType 模式的自动装配。

autodetect

如果发现默认的构造方法,则用 constructor 模式,否则用 byType 模式。

no

默认情况下,不使用自动装配,Bean 依赖必须通过 ref 元素定义。

Spring自动装配Bean

byName-----根据成员变量的name自动装配,如果类对象名称和另一个类中的成员变量的name相同,则自动装配

package com.wangxing.demo;

public class StudentBean {

    public void testStudent(){

        System.out.println("StudentBean的实例方法");

    }

}

package com.wangxing.demo;

public class PersonBean {

    private  StudentBean studentBean;

    public StudentBean getStudentBean() {

        return studentBean;

    }

    public void setStudentBean(StudentBean studentBean) {

        this.studentBean = studentBean;

    }

    public  void  testPerson(){

        System.out.println("PersonBean类的实例方法");

        studentBean.testStudent();

    }

}

<bean id="studentBean" class="com.wangxing.demo.StudentBean"></bean>

<bean id="person" class="com.wangxing.demo.PersonBean" autowire="byName"></bean>

byType-----根据成员变量的数据类型自动装配,如果类的数据类型与另一个类中成据类型兼容,则自动装配。

package com.wangxing.demo;

public class StudentBean {

    public void testStudent(){

        System.out.println("StudentBean的实例方法");

    }

}

package com.wangxing.demo;

public class PersonBean {

    private  StudentBean studentBean;

    public StudentBean getStudentBean() {

        return studentBean;

    }

    public void setStudentBean(StudentBean studentBean) {

        this.studentBean = studentBean;

    }

    public  void  testPerson(){

        System.out.println("PersonBean类的实例方法");

        studentBean.testStudent();

    }

}

<bean id="student" class="com.wangxing.demo.StudentBean"></bean>

<bean id="person" class="com.wangxing.demo.PersonBean" autowire="byType"></bean>

constructor--根据构造方法的参数的数据类型,进行byType模式的自动装配。

package com.wangxing.demo;

public class StudentBean {

    public void testStudent(){

        System.out.println("StudentBean的实例方法");

    }

}

package com.wangxing.demo;

public class PersonBean {

    private  StudentBean studentBean;

    public PersonBean(StudentBean studentBean){

        this.studentBean=studentBean;

    }

    public  void  testPerson(){

        System.out.println("PersonBean类的实例方法");

        studentBean.testStudent();

    }

}

<bean id="student" class="com.wangxing.demo.StudentBean"></bean>

<bean id="person" class="com.wangxing.demo.PersonBean" autowire="constructor"></bean>

autodetect---如果发现默认的构造方法,则用 constructor 模式,否则用 byType 模式。

            Spring3.0以后被淘汰

no---默认情况下,不使用自动装配,Bean 依赖必须通过 ref 元素定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Java-请多指教

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

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

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

打赏作者

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

抵扣说明:

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

余额充值