Spring——IOC操作Bean管理的两种方式

本文详细介绍了Spring中管理Bean的两种主要方式:基于XML的配置和基于注解的方式。XML配置涵盖了bean的创建、属性注入、集合属性注入、外部bean注入等,而注解方式则包括了@Component系列注解、@Autowired、@Qualifier、@Resource和@Value等。这两种方式都旨在简化对象创建和依赖注入,实现控制反转。

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

IOC操作Bean管理的两种方式

  1. Bean管理指的是两个操作
  2. Spring创建对象
  3. Spring注入属性

Bean管理操作有两种方式

  1. 基于xml配置文件方式实现
  2. 基于注解方式实现

IOC操作Bean管理(基于xml方式)

class book{
    private String bname;
    private String bauthor;
    public void setBname(String bname){
        this.bname=bname;
    }
    public void setBauthor(String bauthor){
        this.bauthor=bauthor;
    }
    public void testDemo(){
        System.out.println(bname+"  "+bauthor);
    }
}

class test{
	public static void main(String args[]){
        ApplicationContext demo=new ClassPathXmlApplicationContext("src/beans.xml");
        book test=demo.getBean("book",book.class);
        test.testDemo();
    }
}

基于xml创建对象

<bean id="book" class="src.com.xf.spring.book"></bean>

基于xml方式注入属性

<bean id="book" class="src.com.xf.spring.book">
    <property name="bname" value="a coat"></property>
    <property name="bauthor" value="xf"></property>
</bean>

bean管理xml注入

  1. 在spring配置文件中,使用bean标签,标签里添加相应属性就可以实现对象创建
  2. 在bean标签有很多属性,常用属性:id属性:唯一标识 class属性:类全路径
  3. 创建时候,默认也是执行无参数构造方法完成创建对象

基于xml方式注入属性

DI:依赖注入,就是注入属性

第一种注入方式:使用set方法进行注入(如上述例子)

第二种注入方式:使用有参构造进行注入

​ 创建类,定义属性,创建属性对应含参构造方法

public class order {
    private String name;
    private String address;

    public order(String name, String address) {
        this.name = name;
        this.address = address;
    }
    public void testDemo(){
        System.out.println(name+"  "+address);
    }
}
<bean id="order" class="src.com.xf.spring.order">
        <constructor-arg name="name" value="xf"></constructor-arg>
        <constructor-arg index="1" value="china"></constructor-arg>
    </bean>
public class testDemo {

    public static void main(String args[]){
        ApplicationContext demo=new ClassPathXmlApplicationContext("src/beans.xml");
        order test=demo.getBean("order",order.class);
        test.testDemo();
    }
}

p名称空间注入

  1. 使用p名称空间注入,可以简化xml配置方式(用于set方法注入)

    第一步 添加p名称空间在配置文件中

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    

    第二步 进行属性注入,在bean标签里进行操作

    <bean id="book" class="src.com.xf.spring.book" p:bname="a coat" p:bauthor="xf"></bean>
    

IOC操作Bean管理(xml注入其他类型属性)

1.字面量

  • null值

    <property name="address">
                <null/>
            </property>
    
  • 属性值包含特殊符号

    转义符:&lt ; &gt

    <![CDATA[<>]]>
 <property name="address">
            <value><![CDATA[<<China>>]]></value>
        </property>

注入属性——外部bean

创建两个类service和dao类

在service调用dao里面的方法

public class Service {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void add(){
        System.out.println("add....");
        userDao.update();
    }
}



public interface UserDao {
    void update();
}
public class UserDaoImpl implements UserDao{
    @Override
    public void update() {
        System.out.println("update UserDao");
    }
}

在spring配置文件中进行配置

	<bean id="Service" class="src.service.Service">
        <property name="userDao" ref="UserDaoImpl"></property>
    </bean>
    <bean id="UserDaoImpl" class="src.dao.UserDaoImpl"></bean>

测试

public class testBean {
    public static void main(String args[]){
        ApplicationContext context=new ClassPathXmlApplicationContext("src/beans.xml");
        Service demo=context.getBean("Service",Service.class);
        System.out.println(demo);
        demo.add();
    }
}

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-haZ5XRTb-1656835094286)(C:\Users\罗兴风\AppData\Roaming\Typora\typora-user-images\image-20220628133004700.png)]

注入属性——内部bean和级联赋值

引入:数据库一对多关系

部门department 员工employment

两实体,两个类

public class Department {
    private String dname;
    public void setDname(String dname) {
        this.dname = dname;
    }
    @Override
    public String toString() {
        return "Department{" +
                "dname='" + dname + '\'' +
                '}';
    }
}


public class Employee {
    private String eName;
    private String gender;
    private Department depart;
    public void seteName(String eName) {
        this.eName = eName;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public Department getDepart() {
        return depart;
    }
    public void setDepart(Department depart) {
        this.depart = depart;
    }
    public void test(){
        System.out.println(eName+"  "+gender+"   "+depart);
    }
}

配置bean文件(两种方式,其中一种需包含get方法)

 	<bean id="Employee" class="src.entity.Employee">
        <property name="eName" value="zhang san"></property>
        <property name="gender" value="man"></property>
        <property name="depart" ref="Depart"></property>
<!--        <property name="depart.dname" value="security"></property>-->
    </bean>
    <bean id="Depart" class="src.entity.Department">
        <property name="dname" value="technology"></property>
    </bean>

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LutKeEcJ-1656835094287)(C:\Users\罗兴风\AppData\Roaming\Typora\typora-user-images\image-20220628144542839.png)]

IOC操作Bean管理(xml注入集合属性)

常见集合类:数组、List、Map、Set

创建类(包含常见集合属性)

public class Student {
    private String[] idNum;
    private List<String> name;
    private Map<String,String> course;
    private Set<String> grade;

    public void setIdNum(String[] idNum) {
        this.idNum = idNum;
    }

    public void setName(List<String> name) {
        this.name = name;
    }

    public void setCourse(Map<String, String> course) {
        this.course = course;
    }

    public void setGrade(Set<String> grade) {
        this.grade = grade;
    }
    public void test(){
        System.out.println(Arrays.toString(idNum));
        System.out.println(name);
        System.out.println(course);
        System.out.println(grade);
    }
}

配置xml

<bean id="Student" class="src.entity.Student">
        <property name="idNum">
            <array>
                <value>100321</value>
                <value>103421</value>
                <value>105421</value>
                <value>105421</value>
            </array>
        </property>
        <property name="name">
            <list>
                <value>name1</value>
                <value>name2</value>
                <value>name3</value>
            </list>
        </property>
        <property name="course">
            <map>
                <entry key="9001" value="Java"></entry>
                <entry key="9002" value="SQL"></entry>
                <entry key="9003" value="web"></entry>
            </map>
        </property>
        <property name="grade">
            <set>
                <value>99</value>
                <value>299</value>
                <value>919</value>
                <value>499</value>
                <value>599</value>
            </set>
        </property>
    </bean>

运行结果

public class testBean {
    public static void main(String args[]){
        ApplicationContext context=new ClassPathXmlApplicationContext("src/beans.xml");
        Student demo=context.getBean("Student",Student.class);
        System.out.println(demo);
        demo.test();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zEMklyFP-1656835094288)(C:\Users\罗兴风\AppData\Roaming\Typora\typora-user-images\image-20220628152934505.png)]

在集合里设置对象类型

创建类course,含cname

public class Course {
    private String cname;
    public void setCname(String cname) {
        this.cname = cname;
    }
    @Override
    public String toString() {
        return "Course{" +
                "cname='" + cname + '\'' +
                '}';
    }
}

在student类引用List clist

    public void setClist(List<Course> clist) {
        this.clist = clist;
    }

配置xml文件

<bean id="Student" class="src.entity.Student">
        <property name="clist">
            <list>
                <ref bean="course1"></ref>
                <ref bean="course2"></ref>
            </list>
        </property>
    </bean>
    <bean id="course1" class="src.entity.Course">
        <property name="cname" value="Java"></property>
    </bean>
    <bean id="course2" class="src.entity.Course">
        <property name="cname" value="SQL"></property>
    </bean>

运行结果

    public void test(){
        System.out.println(clist);
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0yEnQMpU-1656835094288)(C:\Users\罗兴风\AppData\Roaming\Typora\typora-user-images\image-20220628172708575.png)]

把集合注入部分提取出来

在spring配置中引入名称空间until

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

提取集合的取值

	<util:list id="c1">
        <value>Java</value>
        <value>SQL</value>
    </util:list>

将提取的值注入

	<bean id="Name" class="src.entity.Student">
        <property name="name" ref="c1"></property>
    </bean>

操作

 	public void setName(List<String> name) {
        this.name = name;
    }
	public void test(){
        System.out.println(name);
    }

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9q4SDiD7-1656835094288)(C:\Users\罗兴风\AppData\Roaming\Typora\typora-user-images\image-20220628175312367.png)]

IOC操作Bean管理(工厂bean)

普通bean与工厂bean(FactoryBean)的区别:

  1. 普通bean的定义的类型就是返回的类型
  2. 工厂bean的定义的类型可以与返回值类型不同

工厂bean的实现方式:

​ 1:让这个类作为工厂bean,实现接口FactoryBean

public class Factor implements FactoryBean<Course> {
    @Override
    public Course getObject() throws Exception {
        Course course=new Course();
        course.setCname("Java");
        return course;
    }
    @Override
    public Class<?> getObjectType() {
        return null;
    }
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

​ 2:实现接口里面的方法,在实现方法中返回bean类型

	public class testBean {
    public static void main(String args[]){
        ApplicationContext context=new ClassPathXmlApplicationContext("src/beans.xml");
        Course demo=context.getBean("myBean",Course.class);
        System.out.println(demo);
    }
}

xml配置

<bean id="myBean" class="src.entity.Factor"></bean>

Bean作用域

1、在Spring里面,设置创建bean实例是单例还是多实例

2、在Spring里面,默认情况下,bean是单实例对象

3、如何设置单实例还是多实例

bean标签里的属性scope

单例实例与多例实例

singleton与prototype之间的区别:

  1. singleton声明单例实例,prototype声明多例实例
  2. singleton在加载配置文件时创建实例对象,prototype在加载配置文件时不创建实例对象,而是在调用XX方法时创建实例对象

xml通过bean标签中的scope属性声明(默认条件下为单例bean)

 <bean id="myBean" class="src.entity.Student" scope="prototype"></bean>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ICCIkeWC-1656835094289)(C:\Users\罗兴风\AppData\Roaming\Typora\typora-user-images\image-20220628211218258.png)]

<bean id="myBean" class="src.entity.Student" scope="singleton"></bean>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nYlD6i9m-1656835094289)(C:\Users\罗兴风\AppData\Roaming\Typora\typora-user-images\image-20220628211255581.png)]

bean的生命周期

  1. 通过构造器创建实例对象(无参构造)

  2. 为bean的属性设置值和对其他bean引用(调用set方法)

  3. 把bean实例传递bean后置处理的方法

  4. 调用bean的初始化方法(需进行配置初始化的方法)

  5. 把bean实例传递bean后置处理器的方法

  6. bean可以使用了(对象获取到了)

  7. 当容器关闭时,调用bean的销毁的方法(需进行配置销毁的方法)

    public class live {
        private String step;
        int i=1;
        public void setStep(String step) {
            this.step = step;
            System.out.println("step"+i+":setProperty");
            i++;
        }
        public live() {
            System.out.println("Step"+i+":no_param construct");
            i++;
        }
        public void Destroy_method(){
            System.out.println("step"+i+":destroy");
            i++;
        }
        public void Init_method(){
            System.out.println("Step"+i+":InitMethod");
            i++;
        }
    }
    
    	public class testBean {
        public static void main(String args[]){
            ApplicationContext context=new ClassPathXmlApplicationContext("src/beans.xml");
            live demo1=context.getBean("Live",live.class);
            System.out.println("step:normal use");
            ((ClassPathXmlApplicationContext)context).close();
        }
    }
    

    配置文件

    	<bean id="Live" class="src.entity.live" init-method="Init_method" destroy-				method="Destroy_method">
            <property name="step" value="step n"></property>
        </bean>
    

    IOC操作Bean管理——Bean自动装配

    什么是自动装配(解决通过property引入外部类)

    根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入

    演示自动装配的过程

    public class Dpt {
        @Override
        public String toString() {
            return "Dpt{}";
        }
    }
    public class Emp {
        private Dpt dpt;
        private String name;
        public void setDpt(Dpt dpt) {
            this.dpt = dpt;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Emp{" +
                    "dpt=" + dpt +
                    ", eName='" + name + '\'' +
                    '}';
        }
        public void test(){
            System.out.println(dpt+"  "+name);
        }
    }
    
    public class testBean {
        public static void main(String args[]){
            ApplicationContext context=new ClassPathXmlApplicationContext("src/beans.xml");
            Emp demo1=context.getBean("emp",Emp.class);
            System.out.println(demo1);
            demo1.test();
        }
    }
    

    ​ 根据属性名称自动注入:bean标签属性autowrite,配置自动装配

    ​ autowrite属性常用两个值:

    ​ byName根据属性名称注入,注入bean的id值和类属性名称一样

    <bean id="emp" class="src.autowire.Emp" autowire="byName"></bean>
    

    ​ 通过类型名称dpt进行外部引入

    byType根据属性类型注入

    <bean id="emp" class="src.autowire.Emp" autowire="byType"></bean>
    

    通过定义的dpt类型进行外部引入

    IOC操作Bean管理(引入外部属性)

    1、直接配置数据库信息

    ​ 配置德鲁伊连接池

    ​ 引入德鲁伊jar包druid

    //配置连接池
    <bean id="" class="com.alibaba.druid.pool.DruidDataSource">
    	<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/userDb"></property>
        <property name="username" vlaue="root"></property>
        <property name="password" vlaue="root"></property>
    </bean>
    

    2、引入外部属性文件数据库连接池

    ​ 1、创建外部属性文件(.property),引入数据库信息

    prop.driverClass=com.mysql.jdbc.Driver
    prop.url=
    prop.userName=
    prop.Password=
    

    ​ 2、把外部properties属性文件引入到spring配置文件中

    ​ 引入contex名称空间

      在spring配置文件中使用标签引入外部属性文件
       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/util http://www.springframework.org/schema/util/spring-util.xsd
                                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:property-placeholder location="classpath:jdbc.properties" />
    
     	配置连接池
    
    //配置连接池
    <bean id=""dataSource class="com.alibaba.druid.pool.DruidDataSource">
    	<property name="driverClassName" value="${prop.driverClass}"></property>
        <property name="url" value="${prop.url}"></property>
        <property name="username" vlaue="${prop.userName}"></property>
        <property name="password" vlaue="${prop.password}"></property>
    </bean>
    

    IOC操作Bean管理(基于注解方式实现对象创建)

​ 什么是注解:

  • 注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属 性名称=属性值)
  • 使用注解,注解作用在类上面,方法上面,属性上面
  • 使用注解目的:简化xml配置

2,Spring针对Bean管理中创建对象提供注解

@Component

@Service

@Controller

@Repository

四个注解功能相同,都可以用来创建bean实例

3,基于注解方式实现对象创建

第一步 引入依赖(基本依赖+spring-aop)

第二部 开启组件扫描

bean文件中引入名称空间context

扫描多个包,多个包使用逗号隔开

扫面包上层目录

<context:component-scan base-package="com.xfd.dao,com.xf.service"></context:component-scan>

第三步 创建类,在类上面添加注解

@Component(value="UserService")
public class UserService{
    public void add(){
        System.out.println("add.....")
    }
}

在注解里面value属性值可以省略不写,默认值是类名称.首字母小写

public class Test{
    public void testService(){
        ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
        UserService userService=context.getBean("userService",UserService.class);
        userService.add();
    }
}

开启组件扫描配置(哪些类需要扫描,哪些类不需要扫描)

//示例1,需要扫描的内容
<context:component-scan base-package="com.xfd.dao,com.xf.service" user-default-filter="false">
    <context:include-filter type="annotion" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
//示例2,不需要扫描的内容
<context:component-scan base-package="com.xfd.dao,com.xf.service" user-default-filter="false">
    <context:exclude-filter type="annotion" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

基于注解方式实现属性注入

xml配置

<context:component-scan base-package="src.service,src.dao"></context:component-scan>

1.@Autowired:根据属性类型进行自动装配

第一步 把service和dao对象创建,在service和dao类添加创建对象注解

第二步 在service注入dao对象,在service类添加dao类型属性,在属性上面使用注解

@Repository(value = "UserDaoImpl")
public class UserDaoImpl implements UserDao{
    @Override
    public void update() {
        System.out.println("update UserDao");
    }
}

@Service
public class service {
    @Autowired
    public UserDaoImpl userDao;
    public void add(){
        System.out.println("add....");
        userDao.update();
    }
}

2.@Qualifler:根据属性名称进行注入,和Autowired一起使用

@Qualifler(value="userDaoImpl")

3.@Resource:可以根据 类型注入,可以根据名称注入

@Resource//根据类型注入
@Resource(name="UserDaoImpl")//根据名称进行注入

4.@Value:注入普通类型属性

public class service {
    @Autowired
    @Qualifier(value = "UserDaoImpl")
    public UserDaoImpl userDao;
    @Value(value = "abc")
    private String name;
    public void add(){
        System.out.println("add...."+name);
        userDao.update();
    }
}

输出结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wqSt75yB-1656835094290)(C:\Users\罗兴风\AppData\Roaming\Typora\typora-user-images\image-20220703152907956.png)]

完全注解开发

创建配置类,替代xml文件(SpringConfig.java)

编写测试类

@Configuration
@ComponentScan(basePackages={"src"})
public class SpringConfig{
    
}

class test{
    public static void main(String args[]){
        ApplicationContext context=new 	AnnotationConfigApplicationContext(SpringConfig.class);
        service demo1=context.getBean("service",service.class);
        System.out.println(demo1);
        demo1.add();
    }
}

称注入

@Resource//根据类型注入
@Resource(name="UserDaoImpl")//根据名称进行注入

4.@Value:注入普通类型属性

public class service {
    @Autowired
    @Qualifier(value = "UserDaoImpl")
    public UserDaoImpl userDao;
    @Value(value = "abc")
    private String name;
    public void add(){
        System.out.println("add...."+name);
        userDao.update();
    }
}

输出结果

[外链图片转存中…(img-wqSt75yB-1656835094290)]

完全注解开发

创建配置类,替代xml文件(SpringConfig.java)

编写测试类

@Configuration
@ComponentScan(basePackages={"src"})
public class SpringConfig{
    
}

class test{
    public static void main(String args[]){
        ApplicationContext context=new 	AnnotationConfigApplicationContext(SpringConfig.class);
        service demo1=context.getBean("service",service.class);
        System.out.println(demo1);
        demo1.add();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Rush006

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

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

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

打赏作者

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

抵扣说明:

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

余额充值