【Spring】(4)IoC - 基于注解的容器配置

【Spring】(4)IoC - 基于注解的容器配置

一、基于注解的容器配置

之前Spring容器一直使用xml配置,现在终于到注解了。毕竟如果一直使用xml配置,类多了配置起来就难受了。

这篇文章开始,使用注解,会非常开心。对以后学习SpringBoot帮助也很大。

注意:这里并不是说xml配置不好,两者各有优缺点,注解和xml的选择需要看情况而定。

1.准备

要使用注解开发,必须要保证aop的包导入了!

并且配置文件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: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">

    <!-- 扫描com.shengjava包下的所有注解 -->
    <context:component-scan base-package="com.shengjava"/>

</beans>

2.代码

项目结构:

在这里插入图片描述

User类。使用了注解 ==@Component、@Scope、@Value==

/**
 * 注解@Component等价于:<bean id="user" class="com.shengjava.pojo.User"/>
 * 该注解会将下面的User类创建对象,命名为小驼峰格式user,并把该对象交给Spring容器ApplicationContext进行管理。
 * 注解@Scope("prototype")等价于:在<bean id="user" class="com.shengjava.pojo.User" scope="prototype"/>中,加了一个 scope="prototype";
 */
@Component
@Scope("prototype")
public class User {
    /**
     *  注解@Value("长生2")等价于:<property name="name" value="长生2"></property>
     *  可以放到set方法上,也可以放到字段上。如果两者都有值,则优先取set方法上的。
     */
    @Value("长生2")
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
    public String getName() {
        return name;
    }
    /**
     * 注解@Value("中国浙江")等价于:<property name="address" value="中国浙江"></property>
     */
    @Value("长生")
    public void setName(String name) {
        this.name = name;
    }
}

UserController类。使用了注解 ==@Controller==

/**
 * 注解@Controller语义为控制器,常用于放在控制跳转的类上,作用和@Component一样。
 */
@Controller
public class UserController {
    /**
     * 自动装配注解@Autowired(放在属性字段上)。通过byType的方式实现。
     * 等价于:<bean id="userService" class="com.shengjava.dao.UserController" autowire="byType"></bean>
     */
    @Autowired
    private UserService userService;
}

UserService类。使用了注解 ==@Service、@Autowired==

/**
 * 注解@Service语义为服务,常用于放在业务服务的类上,作用和@Component一样。
 */
@Service
public class UserService {
    /**
     * 自动装配注解@Autowired(放在属性字段上)。通过byType的方式实现。
     * 等价于:<bean id="userDao" class="com.shengjava.dao.UserDao" autowire="byType"></bean>
     */
    @Autowired
    private UserDao userDao;
}

UserDao类。使用了注解 ==@Repository==。

/**
 * 注解@Repository语义为仓库,常用于放在数据访问的类上,作用和@Component一样。
 */
@Repository
public class UserDao {
}

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

    <!-- 扫描com.shengjava包下的所有注解 -->
    <context:component-scan base-package="com.shengjava"/>

</beans>

测试类

public class AnnotationTest {
    public static void main(String[] args) {
        // 获取xml配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取对象
        User user = context.getBean("user", User.class);
        UserController userController = context.getBean("userController", UserController.class);
        UserService userService = context.getBean("userService", UserService.class);
        UserDao userDao = context.getBean("userDao", UserDao.class);
        // 输出
        System.out.println(user);
        System.out.println(userController);
        System.out.println(userService);
        System.out.println(userDao);
    }
}

输出

User{name='长生'}
com.shengjava.controller.UserController@3e96bacf
com.shengjava.service.UserService@484970b0
com.shengjava.dao.UserDao@4470f8a6

3.注解总结

3.1 bean注解 @Component、@Controller、@Service 和 @Repository

@Component 注解衍生出了其他几个功能一模一样的注解,只是单词不一样而已。
如:@Controller、@Service、@Repository。

这三个对应我们的web开发时候的MVC三层架构分层。

  • 控制层(controller层):使用 @Controller 注解。
  • 业务服务层(service层):使用 @Repository 注解。
  • 数据访问层(dao层):则使用 @Repository 注解。
  • 组件:使用 @Component 注解。

这四个注解会将类创建对象,命名为小驼峰格式user,并把该对象交给Spring容器ApplicationContext进行管理。

例如,User类上面的@Component注解等价于下面这段xml配置:

<bean id="user" class="com.shengjava.pojo.User"/>
3.2 自动装配注解 @Autowired

自动装配注解@Autowired(放在属性字段上)。通过byType的方式实现。

例如,UserController 类 userService 属性上的@Autowired,等价于下面这段xml配置:

<bean id="userService" class="com.shengjava.dao.UserController" autowire="byType"></bean>

你也可以使用注解 @Resouce 注解,作用和 @Autowired 一样,不过是先用过byName,如果byName没找到,再使用byType。

3.3 bean的作用域注解 @Scope

例如,User类上的注解@Scope("prototype")等价于下面这段xml:

<bean id="user" class="com.shengjava.pojo.User" scope="prototype"/>
3.4 @Value

@Value 通常用于注入外部属性。详情:1.9.8. Using @Value

例如,User类name属性上的注解@Value("长生2")等价于如下xml:

@Value可以放到set方法上,也可以放到字段上。如果两者都有值,则优先取set方法上的。

<property name="name" value="长生2"></property>

参考自:1.9. Annotation-based Container Configuration