Spring的总结

24 阅读11分钟

初始 Spring

Spring 的官方文档 Spring Framework Overview :: Spring Framework

Spring 文档目录 docs.spring.io/spring-fram…

Spring 中文文档 Spring Framework 中文文档 (springdoc.cn)

什么是spring?

Spring是一个轻量级Java开发框架,最早有Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此Java开发者可以专注于应用程序的开发。Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发。

Spring可以做很多事情,它为企业级开发提供给了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入(dependency injection,DI)和面向切面编程(aspect-oriented programming,AOP)

为了降低Java开发的复杂性,Spring采取了以下4种关键策略

  • 基于POJO的轻量级和最小侵入性编程;
  • 通过依赖注入和面向接口实现松耦合;
  • 基于切面和惯例进行声明式编程;
  • 通过切面和模板减少样板式代码。

Spring框架的核心是什么?

Spring框架的核心:IoC容器和AOP模块。通过IoC容器管理POJO对象以及他们之间的耦合关系;通过AOP以动态非侵入的方式增强服务。

IoC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。

Spring 的优缺点

优点

  • 对象的创建和依赖关系的维护,解耦,简化开发
  • AOP面向切面编程,方便实现程序对权限的拦截,运行监控等
  • 可配置的声明式事务
  • 单元测试Spring程序
  • 方便集成其他框架
  • 降低负责的api 应用

缺点

  • Spring 依赖反射,反射影响性能
  • 具有门槛

Spring由哪些模块组成?

Spring 总共大约有 20 个模块, 由1300多个不同的文件构成。 而这些组件被分别整合在核心容器(Core Container) 、 AOP(Aspect Oriented Programming)和设备支持(Instrmentation) 、数据访问与集成(Data Access/Integeration) 、 Web、 消息(Messaging) 、 Test6 个模块中。这个版本5.0.0.RC2的文档中可以找到这张图

image.png

Spring 框架中都用到了哪些设计模式?

1、工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
2、单例模式:Bean默认为单例模式;
3、代理模式:SpringAOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
4、模板方法:用来解决代码重复的问题比如.RestTemplate,JmsTemplate,JpaTemplate
5、观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被自动更新,如Springlistener的实现ApplicationListener

Spring Bean的作用域和生命周期

当您创建bean定义时,您创建了一个配方,用于创建由该bean定义定义的类的实际实例。bean定义是一个配方的想法很重要,因为这意味着,就像一个类一样,您可以从单个配方创建许多对象实例。

您不仅可以控制要插入到从特定bean定义创建的对象中的各种依赖项和配置值,还可以控制从特定bean定义创建的对象的范围。这种方法功能强大且灵活,因为您可以选择通过配置创建的对象的范围,而不必在Java类级别烘焙对象的范围。Bean可以定义为部署在多个范围中的一个。Spring Framework支持六个范围,其中四个只有在您使用支持WebApplication ationContext时才可用。您还可以创建自定义范围。

下表描述了支持的范围:

image.png

Bean的生命周期可以简单分为:实例化BeanBean对象的属性赋值,初始化,销毁

推荐文章 如何记忆 Spring Bean 的生命周期 - 掘金 (juejin.cn)

image.png

搭建一个 Spring 项目

新建一个空的 Maven 项目

引入相关的依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.9</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.26</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>1.3.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.7</version>
    </dependency>

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.25</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.9</version>
    </dependency>

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.5</version>
    </dependency>
</dependencies>

添加相关的 jdk 版本

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
</properties>

添加 Maven 资源文件的打包构建,刷新 Maven 项目确保最新,更新可能慢,重启或者直接把 xml 文件放在 target 目录 classes 目录下

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

或者,都试一下,可能 idea没识别到

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.*</include>
            </includes>
        </resource>
    </resources>
</build>

IOC 控制反转

原始实现业务之间的调用:新建一个用户接口,内部包含了获取用户的方法

public interface UserDao {
    void getUser();
}

获取用户具有三种实现,MYSQL、ORACLE、Redis 中获取用户的具体实现

public class UserDaoMysqlImpl implements UserDao{

    public void getUser() {
        System.out.println("UserDaoMysqlImpl--->getUser方法");
    }
}


public class UserDaoOracleImpl implements UserDao{
    public void getUser() {
        System.out.println("UserDaoOracleImpl--->getUser方法");
    }
}


public class UserDaoRedisImpl implements UserDao{
    public void getUser(){
        System.out.println("得到了UserDaoRedisImpl--->getUser方法");
    }
}

业务层实现方法的调用:

public interface UserService {
}

具体的实现

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoOracleImpl();

    public void getUser() {
        userDao.getUser();
    }
}

用户端的测试

    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
        userService.getUser();
    }

这样流程之后,用户想获取其他数据库的具体实现,就必须在业务代码的实现中修改依赖的实现 private UserDao userDao = new UserDaoOracleImpl();

IOC 控制反转的实现,通过 set 的方式注入对象,自定义性更高

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void getUser() {
        userDao.getUser();
    }

    //set的动态注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

用户测试传入具体注入对象,业务自动获取具体的实现完成功能,业务代码无需改动或者改动很小

    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(new UserDaoMysqlImpl());
        userService.getUser();
    }

通过构造器方式注入

public UserServiceImpl(UserDao userDao) {
    this.userDao = userDao;
}

在调用业务实现的时候就必须通过构造参数进行注入

public static void main(String[] args) {
    UserServiceImpl userService = new UserServiceImpl(new UserDaoRedisImpl());
    userService.getUser();
}

Spring 通过配置文件实现继续在用户端简化传入 new 对象的传入参数,在 resources 目录下建立 beans.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="mysqlImpl" class="com.mao.dao.UserDaoMysqlImpl"></bean>
    <bean id="oracleImpl" class="com.mao.dao.UserDaoOracleImpl"></bean>

    <bean id="UserServiceImpl" class="com.mao.service.UserServiceImpl">
        <property name="userDao" ref="mysqlImpl"></property>
    </bean>

</beans>

这样每一个 bean 标签对应的就是一个对象,只不过这些对象都交给 Spring 进行了托管

用户测试方法,可以直接调用对象,这样用户端什么都不需要改动,只需要改变下配置文件业务实现引入的具体的属性 bean 即可

public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    UserDao mysqlImpl = (UserDao) context.getBean("oracleImpl");
    mysqlImpl.getUser();
    UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");
    userServiceImpl.getUser();

}

可以通过 xml 配置一些常量或者对象映射的值

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Hello {
    private String str;
}

建立配置文件

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="hello" class="com.mao.pojo.Hello">
        <property name="str" value="Spring"/>
    </bean>

</beans>

用户端测试

@Test
public void Test01(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    Object hello = context.getBean("hello");
    System.out.println(hello.toString());
}

IOC 创建对象的方式

1、使用无参构造创建对象、默认

创建实例类,默认无参构造,且不用体现出

public class User {

    private int id;
    private String name;



    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

//    public User() {
//        System.out.println("User的无参构造函数!");
//    }

    public String getName() {
        return name;
    }

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

    public void show(){
        System.out.println("name="+name);
        System.out.println("id="+id);
    }
}

配置文件实现,property 属性默认走的是无参构造,通过建一个有参构造就会爆没有初始化参数构造器异常

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.mao.pojo.User">
        <property name="name" value="666"></property>
        <property name="id" value="1"></property>
    </bean>
</beans>

用户端测试,在创建 bean 的时候,就实例化了

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        User user = context.getBean("user",User.class);
        User user2 = context.getBean("user",User.class);
        user.show();
        System.out.println("---------"+user.equals(user2)+"----------");
    }

2、有参构造创建对象-下标索引创建,有参构造必须显示的定义有参构造器

修改配置文件,每一个 beanid 必须唯一

<bean id="user1" class="com.mao.pojo.User">
    <constructor-arg index="0" value="1"></constructor-arg>
    <constructor-arg index="1" value="name1"></constructor-arg>
</bean>

3、有参构造创建对象-参数类型创建

修改配置文件

<bean id="user2" class="com.mao.pojo.User">
    <constructor-arg type="int" value="3"></constructor-arg>
    <constructor-arg type="java.lang.String" value="name3"></constructor-arg>
</bean>

4、有参构造创建对象-参数名创建

修改配置文件

<bean id="user3" class="com.mao.pojo.User">
    <constructor-arg name="id" value="123"></constructor-arg>
    <constructor-arg name="name" value="name4"></constructor-arg>
</bean>

测试方法都一样,只需要修改获取 bean 的名称就行,通过 Spring 的创建出的对象都是单例的,对象相等,将每个对象的 bean 添加到这个配置文件中每次获取这个配置文件时候对象都对加载一次

添加多个配置文件

新建配置文件 applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="bean1.xml"></import>
    <import resource="bean2.xml"></import>
</beans>

别名配置

新增实体类

public class UserT {
    private String name;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("name="+name);
    }
}

bean1.xml 配置

<alias name="userT" alias="asdfghjkjdfsd"></alias>

<bean id="userT" class="com.mao.pojo.UserT" name="123,456">
    <property name="name" value="666"></property>
</bean>

测试,别名可以通过 alias 标签配置,也可以通过 bean 标签的 name 属性进行配置

public static void main(String[] args) {
        // 别名
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserT user1 = context.getBean("asdfghjkjdfsd", UserT.class);
        user1.show();

        UserT bean1 = context.getBean("123", UserT.class);
        bean1.show();

        UserT bean = context.getBean("456", UserT.class);
        bean.show();
}

xml 为初始化对象 DI

新建 Address

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Address {
    private String address;
}

新建 Student

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobby;
    private Map<String,String> card;
    private Set<String> games;
    private String wife; //空指针
    private Properties info;
}

建立配置文件 applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="address" class="com.mao.pojo.Address">
        <property name="address" value="add"></property>
    </bean>
    
    <bean id="student" class="com.mao.pojo.Student">
        <property name="name" value="name1"></property>
        <property name="address" ref="address"></property>
        <property name="books">
            <array>
                <value>红楼梦1</value>
                <value>红楼梦2</value>
                <value>红楼梦3</value>
            </array>
        </property>

        <property name="hobby">
            <list>
                <value>敲代码1号</value>
                <value>敲代码2号</value>
                <value>敲代码3号</value>
            </list>
        </property>

        <property name="card">
            <map>
                <entry key="身份证" value="1"></entry>
                <entry key="银行卡" value="12"></entry>
                <entry key="手机号" value="123"></entry>
            </map>
        </property>

        <property name="games">
            <set>
                <value>LOL</value>
                <value>COC</value>
                <value>王者荣耀</value>
            </set>
        </property>

        <property name="wife">
            <null></null>
        </property>

        <property name="info">
            <props>
                <prop key="url">www.baidu.com</prop>
                <prop key="手机号">1</prop>
                <prop key="password">12</prop>
                <prop key="年龄">123</prop>
            </props>
        </property>
    </bean>
</beans>

用户端测试

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

p 命名空间和 c 命名空间

新建实体

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private int age;
}

p 命名空间和 c 命名空间

<?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/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.mao.pojo.User" p:age="18" p:name="User P命名空间要有无参构造" scope="prototype">
    </bean>

    <bean id="userC" class="com.mao.pojo.User" c:age="20" c:name="User C命名空间要有有参构造" scope="singleton">
    </bean>
</beans>

测试命名空间,首先需要在配置文件中导入命名空间作用域

@Test
public void testPC(){
    ApplicationContext context = new ClassPathXmlApplicationContext("userBean.xml");
    User user = context.getBean("user", User.class);
    User user2 = context.getBean("user", User.class);
    System.out.println(user);
    // 全局共享一个singleton默认    prototype---->false
    System.out.println("---------"+user.equals(user2)+"------------");

    User userC = context.getBean("userC", User.class);
    System.out.println(userC);

    System.out.println("---------"+user.equals(userC)+"------------");
}

scope 作用域包含单例模式和原型模式。

自动装配 bean

  • 自动装配是 Spring 中的满足 bean 依赖的一种方式
  • Spring 会在上下文中自动寻找,自动给 bean 装配属性

Spring 中有三种装配的方式:xml 中显示的配置、java 中显示的配置、隐式的自动装配 bean

新建人员实体

public class People {
    private Cat cat;
    private Dog dog;
    
    private String name;
    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "People{" +
                "cat=" + cat +
                ", dog=" + dog +
                ", name='" + name + ''' +
                '}';
    }

}

宠物实体

public class Dog {

    public void shout(){
        System.out.println("Hwang,Hwang~");
    }
}

public class Cat {
    public void shout(){
        System.out.println("miaow,miaow~");
    }
}

建立配置文件 applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="cat" class="com.mao.pojo.Cat"/>
    <bean id="dog" class="com.mao.pojo.Dog"/>

    <bean id="people" class="com.mao.pojo.People">
        <property name="name" value="name1"></property>
        <property name="cat" ref="cat"></property>
        <property name="dog" ref="dog"></property>
    </bean>

</beans>

测试方法

@Test
public void test1() {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    People people = context.getBean("people", People.class);
    System.out.println(people);
    people.getCat().shout();
    people.getDog().shout();
}

修改配置文件,byName 自动装配,在容器中自动查找,和自己对象 set 方法后面的值匹配的 beanid

<bean id="cat" class="com.mao.pojo.Cat"/>
<bean id="dog" class="com.mao.pojo.Dog"/>

<bean id="people" class="com.mao.pojo.People" autowire="byName">
    <property name="name" value="name1"></property>
</bean>

修改配置文件,byType 容器中查找和自己对象属性相同的 bean,保证这个类型全局唯一

<bean id="cat" class="com.mao.pojo.Cat"/>
<bean id="dog" class="com.mao.pojo.Dog"/>

<bean id="people" class="com.mao.pojo.People" autowire="byType">
    <property name="name" value="name1"></property>
</bean>
  • 注解实现自动装配 jdk1.5Spring2.5 就开始支持了

导入约束和配置注解支持

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

        <context:annotation-config/>
</beans>

配置文件中添加 bean

<bean id="cat" class="com.mao.pojo.Cat"/>
<bean id="dog" class="com.mao.pojo.Dog"/>
<bean id="people" class="com.mao.pojo.People"/>

在实体的属性直接使用 @Autowired @Autowird默认的注入方式为byType,也就是根据类型匹配,当有多个实现时,则通过byName注入,也可以通过配合@Qualifier注解来显式指定name值,指明要使用哪个具体的实现类

@Autowired
private Cat cat;
@Autowired
private Dog dog;

别名 @Qualifier 指定别名,指定自动装配的

@Autowired
private Cat cat;
@Autowired
@Qualifier("a")
private Dog dog;

private String name;
<context:annotation-config/>
<bean id="cat" class="com.mao.pojo.Cat"/>
<bean id="a" class="com.mao.pojo.Dog"/>
<bean id="people" class="com.mao.pojo.People"/>

java 的自动装配注解 @Resource@Resource默认通过byName注入,如果没有匹配则通过byType注入 @Resource 倾向于确定性的单一资源,@Autowired为类型去匹配符合此类型所有资源。

@Resource
private Cat cat;
@Resource
private Dog dog;

@Resource:应对四个场景

// 1. 默认方式:byName
@Resource  
private UserService userDao; 

// 2. 指定byName
@Resource(name="userService")  
private UserService userService; 

// 3. 指定byType
@Resource(type=UserService.class)  
private UserService userService; 

// 4. 指定byName和byType
@Resource(name="userService",type=UserService.class)  
private UserService userService; 

使用注解开发

1、bean

Spring4之后,要使用注解开发,就必须导入依赖,主要是spring-aop的依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.9</version>
</dependency>

实现配置文件,注解驱动支持,指定要扫描的包

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

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

编写实体,注入为组件,配置文件中就可以扫描到组件,添加这个组件注解就相当于在配置文件中添加 <bean id="user" class="com.mao.pojo.User"></bean>

@Component
public class User {
     public String name = "name1";
}

用户测试

    @Test
    public void Test01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("user", User.class);
        System.out.println(user.name);
    }

2、属性如何注入

修改实体,通过注解给属性赋值

@Component
public class User {
    @Value("name2")
    public String name;
}

3、衍生的注解

由于业务的衍生区分不同结构的业务注解,功能都是将这个类注入到 Spring 中,装配 Bean

@Repository    // dao
@Service       // service
@Controller    // controller

@Mapper 不是 component 的衍生注解

4、作用域

@Scope("prototype") 注入为原型模式,默认是单例模式

使用 javaConfig 实现配置

@Component
public class User {
    private int id;
    private String name;

    @Value("111")
    public void setId(int id) {
        this.id = id;
    }

    @Value("name1")
    public void setName(String name) {
        this.name = name;
    }
}

编写配置类

@Configuration
@ComponentScan("com.mao.pojo")
@Import(Config2.class)
public class Config1 {

    @Bean
    public User getUser(){
        return new User();
    }
}

测试类

@Test
public void test01(){
    ApplicationContext context = new AnnotationConfigApplicationContext(Config1.class);
    User getUser = context.getBean("getUser", User.class);
    System.out.println(getUser);
}