Spring学习总结(七):基于注解装配Bean

一、常用注解的介绍

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

1、用于创建对象的注解

      用于创建对象的注解相当于在bean.xml中配置<bean id="" class=""></bean>

      (1)@Component:用于将当前类对象存入spring容器中,value属性用于指定bean的id。当不写时,默认值是当前类名,且首字母小写。

      (2)@Controller:通常作用在控制层(Controller层),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

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

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

      (5)关于context:component-scan的说明

      1)使用 context 命名空间的 component-scan 元素进行注解的扫描,其 base-package 属性用于通知 spring 所需要扫描的目录。如下:

   <context:component-scan base-package="com.yht.example4"></context:component-scan>

      2)如果同时需要扫描多个包,有两种实现方式:

      假设现在要扫描controller、service和dao三个包:

      方式一:多个包之间使用逗号隔开。

   <context:component-scan base-package="com.yht.example4.controller,com.yht.example4.service,com.yht.example4.dao"></context:component-scan>

      方式二:配置扫描多个包的相同父目录。

   <context:component-scan base-package="com.yht.example4"></context:component-scan>

      3)配置给定包下要扫描哪些包——只扫描controller包和service包:

     <!--  
        use-default-filters:设置为false,不使用默认的过滤规则。
        include-filter:设置哪些包要扫描
      -->
   <context:component-scan base-package="com.yht.example4" use-default-filters="false">
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
       <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
   </context:component-scan>

      4)配置给定包下不扫描哪些包——不扫描controller包

    <!--
       exclude-filter:设置哪些包不扫描
     -->
    <context:component-scan base-package="com.yht.example4" use-default-filters="false">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

      (6)案例:模拟UserSerive调用UserDao——注解方式实现

      1)在xml中配置注解扫描的包。

   <context:component-scan base-package="com.yht.example4"></context:component-scan>

      2)创建UserService和IUserDao以及它的实现类UserDaoImpl,并加入注解。

@Service
public class UserService {
    @Autowired
    private IUserDao userDao;
    public void execute(){
        System.out.println("service的execute()方法");
        userDao.findUser();
    }
}
public interface IUserDao {
    void findUser();
}
@Repository
public class UserDaoImpl implements IUserDao {
    @Override
    public void findUser() {
        System.out.println("UserImpl1 的findUser()");
    }
}

      3)进行测试。     

@Test
    public void  testAnno(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean6.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.execute();
    }

      执行结果如下:

       

2、用于注入值的注解

      用于注入值的注解相当于在bean.xml中给bean对象注入值的操作,<property name="" value=""></property>或<property name="" ref=""></property>

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

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

      在上述例子中,如果IUserDao的子类有多个,那么此时@Autowired就会无法判断选择哪个子类进行注入,所以就需要@Autowired和@Qualifier一起使用。

      在添加两个dao的实现类,此时就会报错如下:

      No qualifying bean of type 'com.yht.example4.dao.IUserDao' available: expected single matching bean but found 3: userDaoImpl,userImpl1,userImpl2。

      为service中的userDao对象添加@Qualifier注解即可解决此问题。如下:

    @Autowired
    @Qualifier(value = "userImpl1")
    private IUserDao userDao;

      执行结果如下:

      (3)@Resource:既可以按照属性注入,也可以按照类型注入,@Resource是Java提供的,而不是Spring提供的。使用如下:

   @Resource(name = "userImpl2")
    private IUserDao userDao;

      执行结果如下:

 

      (4)@Value:用于注入基本类型和String类型的数据。给userService添加一个基本属性:name,使用@Value注入值并输出。

    @Value("User Service")
    private String name;

      结果如下:

3、用于改变作用范围的注解

      @Scope:用于指定bean的作用范围,其属性值value指定范围的取值,常用取值:singleton、prototype。

4、用于生命周期相关的

      (1)@PreDestory:用于指定销毁方法。

      (2)@PostConstruct:用于指定初始化方法。

5、其他新注解

      (1)@Configuration:被注解的类是一个配置类。

      (2)@ComponentScan:通过注解指定spring在创建容器时要扫描的包。和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。相当于XML中的<context:component-scan base-package="com.day2"></context:component-scan>

      (3)@Import:导入其他的配置类。

      (4)@Bean:用于把当前方法的返回值作为bean对象存入spring的ioc容器中

二、纯注解开发案例——无配置文件

      模拟三层架构:查找用户。

      目录结构如下:

      1、MySpringConfig类作为配置类,代替原来的xml文件。

//作为配置类,代替xml
@Configuration
@ComponentScan("com.yht.example5")
public class MySpringConfig {
}

      2、控制层的UserController

@Controller
public class UserController {
    @Autowired
    private IUserService userService;
    public void isExist(){
        System.out.println("controller层:判断用户是否存在");
        userService.findUser();
    }
}

      3、service层的IUserService以及实现类。

public interface IUserService {
    void findUser();
}
@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private IUserDao userDao;
    @Override
    public void findUser() {
        System.out.println("service层:查找用户");
        userDao.query();
    }
}

4、dao层的IUserdao以及实现类

public interface IUserDao {
    void query();
}
@Repository
public class UserDaoImpl implements IUserDao {

    @Override
    public void query() {
        System.out.println("dao层:数据库查询");
    }
}

      4、单元测试

    @Test
    public void  test(){
        ApplicationContext context = new AnnotationConfigApplicationContext(MySpringConfig.class);
        UserController userController = context.getBean("userController", UserController.class);
        userController.isExist();
    }

      结果如下:

猜你喜欢

转载自blog.csdn.net/weixin_47382783/article/details/112784055