学习笔记——Spring(1)helloword--配置bean

介绍

Spring是开源的、轻量级Java开发框架,所谓轻量级指的是:Spring框架在系统初始化时不需要加载所有的服务,节省了系统资源。Spring作用是:简化应用程序开发工作。Spring是一个容器,它包含并且管理应用对象的生命周期。此外可以整合其他的框架。

Spring核心:IOC(或DI)和AOP

IOC:控制反转

资源获取方向反。传统的创建对象方式是在代码中通过“new”关键字来创建对象并通过setter方法对属性进行赋值,而IOC是专门一个容器来创建这些对象。也就是说对对象的控制权从我们开发人员手中转移到了IOC容器上,我们只需要通过一种合适的方式接受资源即可。DI:依赖注入,与IOC是一回事,只不过是从另一个角度进行描述Spring,我理解为:以一种预先定义好的方式(如setter方法、构造器)去接受来自容器的资源注入。

AOP:面向切面编程

项目中抽取出来的与实际业务逻辑无关但又因为可以实现特定功能的、是各个模块公用的特殊模块,当其他模块需要应用是,就将其插入到所需要的位置。

 

Spring配置bean

1、准备工作

(1)新建maven项目,导入Spring依赖jar包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.test</groupId>
    <artifactId>basic_spring</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <spring-version>4.2.6.RELEASE</spring-version>
    </properties>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring-version}</version>
    </dependency>
</dependencies>
</project>

(2)在java/resource目录下创建Spring的xml文件

(3)在java/main目录下创建实体类,并为属性设置getter和setter方法,重写toString()方法(非必须);新建检测类创建主函数

2、使用Spring的xml文件配置bean

2.1、xml文件配置bean的方式

Spring配置文件配置:

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

    <!--
        id:通过id值获取IOC容器中的bean实例
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求类中必须要有无参构造方法
    -->
    <bean id="student1" class="entity.Student">

    </bean>
</beans>

检测类读取文件,并获取bean实例:

package controller;

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

public class Main {
    public static void main(String[] args){
//        读取配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-bean.xml");
//        获取bean 通过id值获取
//        Student student = (Student)ctx.getBean("student1");
//        获取bean 通过类型获取 如果配置文件中只有一个该类型bean,可以使用这种方式,如果有多个该类型bean,则会抛出异常
        Student student = (Student)ctx.getBean(Student.class);
        System.out.println(student);
    }
}

运行结果:

获取bean实例成功;

2.1.1、配置文件注入bean的属性值

(1)setter方法注入

配置方式:

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

    <!--
        id:通过id值获取IOC容器中的bean实例
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求类中必须要有无参构造方法
    -->

    <!--setter方法注入-->
    <bean id="student1" class="entity.Student">
        <property name="id" value="1"></property>
        <property name="name" value="jack"></property>
        <property name="gender" value="男"></property>
        <property name="liveCountry" value="北京"></property>
    </bean>
    <bean id="student2" class="entity.Student">
        <property name="id" value="2"></property>
        <property name="name" value="rose"></property>
        <property name="gender" value="女"></property>
        <property name="liveCountry" value="北京"></property>
    </bean>
</beans>

文件中配置了两个同类型bean,因此检测类中不能类型获取bean,要按id获取,代码:

package controller;

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

public class Main {
    public static void main(String[] args){
//        读取配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-bean.xml");
//        获取bean 通过id值获取
        Student student1 = (Student)ctx.getBean("student1");
        Student student2 = (Student)ctx.getBean("student1");
//        获取bean 通过类型获取 如果配置文件中只有一个该类型bean,可以使用这种方式,如果有多个该类型bean,则会抛出异常
//        Student student = (Student)ctx.getBean(Student.class);
        System.out.println(student1);
        System.out.println(student2);
    }
}

执行结果:

(2)构造方法注入

首先我们为实体类添加一个或一些构造函数,代码:

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

    public Student(Integer id, String name) {
        System.out.println("student含id、name的构造函数");
        this.id = id;
        this.name = name;
    }

    public Student(Integer id, String name, String gender, String liveCountry) {
        System.out.println("student含id、name、gender、liveCountry的构造函数");
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.liveCountry = liveCountry;
    }

配置文件进行配置:

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

    <!--
        id:通过id值获取IOC容器中的bean实例
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求类中必须要有无参构造方法
    -->

    <bean id="student1" class="entity.Student">
        <!--name:属性名;value:属性值-->
        <!--<constructor-arg value="tom" name="name"></constructor-arg>
        <constructor-arg value="1" name="id"></constructor-arg>-->

        <!--index:构造器参数下标;value:属性值-->
        <!--<constructor-arg value="tom" index="1"></constructor-arg>
        <constructor-arg value="1" index="0"></constructor-arg>-->

        <!--type:参数类型;value:属性值  根据重载,参数列表不会相同,所以可以通过指定参数类型为属性赋值,相同类型参数从上到下按序赋值-->
        <constructor-arg value="tom" type="java.lang.String"></constructor-arg>
        <constructor-arg value="1" type="java.lang.Integer"></constructor-arg>
        <constructor-arg value="男" type="java.lang.String"></constructor-arg>
        <constructor-arg value="北京" type="java.lang.String"></constructor-arg>

    </bean>
</beans>

(3)其他细节

很多时候,实体类中不仅仅只有基础数据类型和String,经常会存在集合、数组、其他类引用,下面,针对这些类型数据的配置进行介绍。

a:当实体类中有其他类引用

如Student类中有老师Teacher类的引用,用于标识学生的老师信息。创建Teacher类包含属性t_id、t_name、t_age,在学生类中增加Teacher类型属性,并建立setter方法。

配置文件中配置Student类引用Teacher:

方式1:引用其他bean

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

    <!--
        id:通过id值获取IOC容器中的bean实例
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求类中必须要有无参构造方法
    -->
    <bean id="teacher1" class="entity.Teacher">
        <property name="t_id" value="1"></property>
        <property name="t_name" value="MrLi"></property>
        <property name="t_age">
            <value>28</value>
        </property>

    </bean>

    <!--通过“ref”,引用teacher1对应的bean-->
    <bean id="student1" class="entity.Student">
        <property name="id" value="1"></property>
        <property name="name" value="jack"></property>
        <property name="teacher" ref="teacher1"></property>
        <!--或写作:-->
        <!--
        <property name="teacher">
            <ref bean="teacher1"></ref>
        </property>
        -->
        <!--如果引用bean中的某个属性不符合条件,可以这样去修改级联属性属性值-->
        <property name="teacher.t_age" value="27"></property>
    </bean>
</beans>

 执行结果:

 

方式2:内部bean

不指向外部创建好的bean,而是内部创建新的bean

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

    <!--
        id:通过id值获取IOC容器中的bean实例
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求类中必须要有无参构造方法
    -->
    <!--创建内部bean,内部bean不需要设置id,内部bean不会被外部使用-->
    <bean id="student1" class="entity.Student">
        <property name="id" value="1"></property>
        <property name="name" value="jack"></property>
        <property name="teacher">
            <bean class="entity.Teacher">
                <constructor-arg name="t_id" value="2"></constructor-arg>
                <constructor-arg name="t_name" value="rose"></constructor-arg>
                <constructor-arg name="t_age" value="27"></constructor-arg>
            </bean>
        </property>
    </bean>
</beans>

运行结果:

方式3:自动装配(少用)

通过设置“autowire”,来进行自动装配bean,具体方式如下:

 

<?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:util="http://www.springframework.org/schema/util"
       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">

    <!--配置Teacher类的bean,id和Student类中的Teacher属性名称一致-->
    <bean id="teacher" class="entity.Teacher">
        <property name="t_id" value="101"></property>
        <property name="t_name" value="MrLi"></property>
        <property name="t_age" value="27"></property>
    </bean>

    <!--设置autowire,byName:根据属性名称装配同名的bean;byType:更具属性类型装配同属性bean(要求只能有一个该类型bean存在,否则抛出异常)-->
    <bean id="student1" class="entity.Student" autowire="byName">
        <property name="id" value="1"></property>
        <property name="name" value="jack"></property>
    </bean>
</beans>

 

 b:实体类中有集合

如:学生需要学习多门学科,在Student类中List属性,里面存放学科名,配置中配置如下:

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

    <!--
        id:通过id值获取IOC容器中的bean实例
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求类中必须要有无参构造方法
    -->
    <bean id="teacher1" class="entity.Teacher">
        <property name="t_id" value="1"></property>
        <property name="t_name" value="MrLi"></property>
        <property name="t_age">
            <value>28</value>
        </property>

    </bean>

    <!--通过list节点,设置list属性值(set属性值同理,设置set节点;数组类型和list类型的配置方式相同)-->
    <bean id="student1" class="entity.Student">
        <property name="id" value="1"></property>
        <property name="name" value="jack"></property>
        <property name="teacher" ref="teacher1"></property>
        <property name="teacher.t_age" value="27"></property>
        <property name="subjects">
            <list>
                <value>数学</value>
                <value>语文</value>
                <value>英语</value>
            </list>
        </property>
    </bean>
</beans>

map集合与list、set配置方式略微不同,因为map含有键值对。如:学生每门功课都有成绩,所以在Student类中增加Map类型属性,键对应学科。值对应成绩,xml具体配置map如下:

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

    <!--
        id:通过id值获取IOC容器中的bean实例
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求类中必须要有无参构造方法
    -->
    <bean id="teacher1" class="entity.Teacher">
        <property name="t_id" value="1"></property>
        <property name="t_name" value="MrLi"></property>
        <property name="t_age">
            <value>28</value>
        </property>

    </bean>

    <bean id="student1" class="entity.Student">
        <property name="id" value="1"></property>
        <property name="name" value="jack"></property>
        <property name="teacher" ref="teacher1"></property>
        <property name="teacher.t_age" value="27"></property>
        <property name="subjects">
            <list>
                <value>数学</value>
                <value>语文</value>
                <value>英语</value>
            </list>
        </property>
        <property name="scoreMap">
            <map>
                <entry key="math" value="100"></entry>
                <entry key="chinese" value="99"></entry>
                <entry key="english" value="98"></entry>
                <!--map的键或值还可以通过key-ref和value-ref引用其他bean-->
                <!--<entry key="english" value-ref="***"></entry>-->
            </map>
        </property>
        <!--此外,还可以通过props节点设置Properties类型属性值-->
        <!--<property name="props">
            <props>
                <prop key="jdbcUrl">jdbc:mysql://127.0.0.1:3306/ent_domain</prop>
            </props>
        </property>-->
    </bean>
</beans>

运行结果:

 

如果,想配置一些公共使用的集合,供其他bean调用,那么可以配置单例的集合bean,方式为:

  • 首先,在xml文件中增加util的引用资源,如下:

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

</beans>
  • 使用<util:list>、<util:set>、<util:map>进行配置,如下:
<?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: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">

    <!--
        id:通过id值获取IOC容器中的bean实例
        class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求类中必须要有无参构造方法
    -->
    <bean id="teacher1" class="entity.Teacher">
        <property name="t_id" value="1"></property>
        <property name="t_name" value="MrLi"></property>
        <property name="t_age">
            <value>28</value>
        </property>

    </bean>

    <!--配置单例的集合bean,供其他bean使用-->
    <util:list id="subjectList">
        <value>数学</value>
        <value>语文</value>
        <value>英语</value>
    </util:list>
    <!--通过list节点,设置list属性值()-->
    <bean id="student1" class="entity.Student">
        <property name="id" value="1"></property>
        <property name="name" value="jack"></property>
        <property name="teacher" ref="teacher1"></property>
        <property name="teacher.t_age" value="27"></property>
        <property name="subjects" ref="subjectList"></property>
    </bean>
</beans>

c:Spring表达式语言——SpEL

Spring的表达式语言简称SpEL,它为bean的属性进行动态赋值提供了便利。例如:

Student类中有个createTime属性,表示为学生创建对象的时间。我们希望createTime的属性值为当前时间,所以在xml文件中配置bean时,可以使用SpEL进行设置时间。如下:

<bean id="student1" class="entity.Student">
        <property name="id" value="1"></property>
        <property name="name" value="jack"></property>
        <property name="teacher" ref="teacher1"></property>
        <property name="teacher.t_age" value="27"></property>
        <property name="subjects" ref="subjectList"></property>
        <!--通过SpEL表达式设置时间值-->
        <property name="createTime" value="#{new java.util.Date()}"></property>
    </bean>

运行结果为:

2.2、通过工厂方法配置bean

2.2.1、通过静态工厂方法创建bean

例子:创建一个类Person作为tudent类和Teacher类的父类,创建PersonFactory工厂类,并添加静态工厂方法,用于创建bean实例,配置文件中使用“factory-method”属性指定静态工厂方法。具体实现如下:

Person类:

package entity;

public class Person {

}

Student类继承Person类:

package entity;

import java.util.Date;
import java.util.List;
import java.util.Map;

public class Student extends Person{
    private Integer id;
    private String name;
    private String gender;
    private String liveCountry;
    private Date createTime;
    private Teacher teacher;
    private List<String> subjects;
    private Map<String,Integer> scoreMap;

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

    public Student(Integer id, String name) {
        System.out.println("student含id、name的构造函数");
        this.id = id;
        this.name = name;
    }

    public Student(Integer id, String name, String gender, String liveCountry) {
        System.out.println("student含id、name、gender、liveCountry的构造函数");
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.liveCountry = liveCountry;
    }

    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 String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getLiveCountry() {
        return liveCountry;
    }

    public void setLiveCountry(String liveCountry) {
        this.liveCountry = liveCountry;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    public List<String> getSubjects() {
        return subjects;
    }

    public void setSubjects(List<String> subjects) {
        this.subjects = subjects;
    }

    public Map<String, Integer> getScoreMap() {
        return scoreMap;
    }

    public void setScoreMap(Map<String, Integer> scoreMap) {
        this.scoreMap = scoreMap;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", liveCountry='" + liveCountry + '\'' +
                ", createTime=" + createTime +
                ", teacher=" + teacher +
                ", subjects=" + subjects +
                ", scoreMap=" + scoreMap +
                '}';
    }
}

Teacher类继承Person类:代码省略

PersonFactory类:

package entity;

/**
 * @Description:静态工厂方法:直接调用工厂类的静态方法就可以返回bean实例
 */
public class PersonFactory {

    public PersonFactory(){
        System.out.println("PersonFactory无参构造");
    }

    /**
     * 静态工厂方法
     * @param type
     * @return Person
     */
    public static Person getPerson(Integer type){
        System.out.println("进入静态工厂方法");
        if(type == 1){
            return new Student(1,"jack");
        } else if(type == 2) {
            return new Teacher(1,"MrLi",27);
        } else {
            return null;
        }
    }
}

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

    <!--使用"factory-method"指定调用的静态工厂方法,如果方法需要传参,则通过“constructor-arg”节点设置参数-->
    <bean id="personFactory" class="entity.PersonFactory" factory-method="getPerson">
        <constructor-arg value="1"></constructor-arg>
    </bean>
</beans>

测试类:

package controller;

import entity.Person;
import entity.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args){
//        读取配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-bean.xml");
//        获取bean 通过id值获取
        Person person = (Person)ctx.getBean("personFactory");
        System.out.println(person);
    }
}

运行结果:

可以看出:在没有创建工厂对象的情况下,直接调用了静态方法,创建了bean实例

 

2.2.2、通过实例工厂方法创建bean

通过静态工厂方法创建bean时,使用的是工厂类中的静态方法,因为静态方法在不创建类的对象时,就可以调用,所以在不创建工厂对象的情况下就能通过调用静态方法,创建了bean实例。通过实例工厂方法创建bean只不过是将工厂类中的静态方法替换为普通方法,这样就需要我们先创建工厂类的对象之后,才能调用工厂方法。具体实现如下:

将PersonFactory类中的静态方法改为非静态方法,配置文件中先创建工厂的bean实例,再通过“factory-bean”和“factory-method”调用工厂方法:

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

    <!--创建工厂bean-->
    <bean id="personFactory" class="entity.PersonFactory">
    </bean>

    <!--使用"factory-bean"指定工厂实例,使用"factory-method"指定调用的工厂方法,如果方法需要传参,则通过“constructor-arg”节点设置参数-->
    <bean id="personFactory2" class="entity.PersonFactory" factory-bean="personFactory" factory-method="getPerson">
        <constructor-arg value="1"></constructor-arg>
    </bean>
</beans>

运行结果:

可以看到:通过实例工厂方法创建bean时,要创建工厂类的实例对象

 

2.3注解方式配置bean

组件扫描:Spring能够从classpath下自动扫描、侦测、实例化具有特定注解的组件,这些特定注解包括:

@Component:基本注解,标识一个受Spring管理的组件

@Responsitory:持久层组件注解

@Service:业务层组件注解

@Controller:控制层组件注解

按照规范,不同的注解最好使用在相应的位置,尽管Spring没有对此做出限制。对于这些特定的注解配置的bean,Spring有默认的命名策略:使用类名,首字母小写,也可以手动设置bean的名称。

因此,使用注解注入需要选择以上注解加在类上。要想让Spring自动扫描这些特定注解,还需要在xml文件中进行声明:

  • 首先,在xml文件中增加context的引用资源,如下:

具体代码:

<?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:util="http://www.springframework.org/schema/util"
       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">

    
</beans>
  • 通过“<context:component-scan base-package=""></context:component-scan>”指定要扫描的包路径,“base-package”会指定一个需要扫描的包,Spring容器将会自动扫描这个包以及子包中的所有类,如果需要指定扫描多个包,可以使用逗号分隔开。例如:
<?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:util="http://www.springframework.org/schema/util"
       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">

    <!--base-package:指定要扫描的包-->
    <!--resource-pattern:如果只想扫描指定包下指定类,则可以通过resource-pattern进行过滤(因为java编译后为.class文件,所有后缀为.class)-->
    <!--当前配置表示:spring将扫描entity包下以“T”开头的类-->
    <context:component-scan base-package="entity" resource-pattern="T*.class">
    </context:component-scan>
</beans>
  • 此外,“<context:component-scan”下可以通过配置“<context:include-filter type="" expression=""></context:include-filter>”或“<context:exclude-filter type="" expression=""></context:exclude-filter>”,指定不扫描或只扫描哪些注解。如:
<?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:util="http://www.springframework.org/schema/util"
       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">

    <!--base-package:指定要扫描的包-->
    <!--resource-pattern:如果只想扫描指定包下指定类,则可以通过resource-pattern进行过滤(因为java编译后为.class文件,所有后缀为.class)-->
    <!--当前配置表示:spring将扫描entity包下以“S”开头的类-->
    <context:component-scan base-package="entity" resource-pattern="S*.class" use-default-filters="false">
        <!--type="annotation":表示通过注解类型控制;type="assignable":表示通过类名控制-->
        <!--不扫描有Component注解的类-->
        <!--<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"></context:exclude-filter>-->
        <!--只扫描有Controller注解的类,使用该配置时要设置‘use-default-filters="false"’,否则配置无效-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></context:include-filter>
    </context:component-scan>
</beans>

配置bean之间关联关系:

当实体类中有其他类引用时,在类中定义指定类型的属性,通过特定注解装配相应bean实例,特定注解包括有:

@Autowired、@Resource、@Inject,将这些类型注解加在定义属性的代码上即可(也可以给属性定义setter方法,将注解加在setter方法上也可以)。

@Autowired:使用该注解时,如果找不到指定的bean时,默认抛出异常,但通过设置属性 required=false 声明找不到bean也不会抛异常。该注解默认先按照类型进行装配,如果找到多个匹配类型的bean,再去其中根据名称装配,可以通过配合使用@Qualifier去指定按名称装配bean。

@Resource:默认先按照备案名称进行装配,匹配不到名称,再按类型装配。如果设置了name属性,则只能按名称装配,如果这设置了type属性,则只能按类型装配。

代码示例:

package controller;

import entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
//使用Controller配置bean
@Controller
public class Main {
//    使用Autowired注解装配bean required = false:如果Student类型的bean还没有配置,也不抛出异常
//    @Autowired(required = false)
//    指定按名称装配bean
//    @Qualifier(value = "student").
//    public Student student;

//    使用Resource注解,并且按名称装配bean
    @Resource(name = "student")
    public Student student;
    public static void main(String[] args){
//        读取配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-bean.xml");
//        获取bean 通过id值获取
        Main main = (Main)ctx.getBean("main");
        System.out.println(main.student);
    }
    public Main(){
        System.out.println("Main无参构造");
    }
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值