• 中文
    • English
  • 注册
  • 查看作者
    • Spring:使用SPEL以及使用注解完成属性的自动注入

      一.  前言

      在使用Spring之前,我们的业务层依赖数据层,而控制层又依赖业务层,也就是在Service里需要new Dao,而在Servlet中又需要new Service。

      有了Spring,我们便可以使用XML或者注解的方式,将Service需要的Dao注入Service或者将Servlet需要的Service注入Servlet,下面以注解的方式为例。

      二.  使用SPEL

      1.  将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:content="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/context https://www.springframework.org/schema/context/spring-context.xsd">
          <content:component-scan base-package="io.zhangjia.spring" />
      
      </beans>

      2.  将BookService修改为:

      package io.zhangjia.spring.service;
      
      import io.zhangjia.spring.dao.BookDao;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Service;
      
      @Service
      public class BookService {
          //    @Value("bookDao") 不能这么写,会当做String字符串处理
          @Value("#{bookDao}")
          private BookDao bookDao;
        
          public BookDao getBookDao() {
              System.out.println("bookDao = " + bookDao);
              return bookDao;
          }
      
          public BookService() {
              System.out.println("BookService.BookService");
          }
      }

      注意,这里的@Value注解,不能再使用  @Value(“bookDao”),而需要使用SPEL,SPEL是Spring的表达式语言,可以通过SPEL引用其他Bean、数学运算或者逻辑判断。 

       @Value(“#{bookDao}”) 意为引用id为bookDao的bean,即BookDao(再次强调一遍,我们并没有手动为BookDao设置ID,但是为其设置了Component注解,所以其默认id即为类名首字母小写:bookDao)

      另外,使用注解的方式甚至可以省略setter方法,所以上面的代码中只提供了getter方法用于测试。

      3.  将BookController修改为:

      package io.zhangjia.spring.controller;
      
      import io.zhangjia.spring.service.BookService;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Controller;
      
      @Controller("zhangjia")
      public class BookController {
          @Value("#{bookService}")
          private BookService bookService;
      
          public BookService getBookService() {
              System.out.println("bookService = " + bookService);
              return bookService;
          }
      
      
          public BookController() {
              System.out.println("BookController.BookController");
          }
      }

      @Controller(“zhangjia”) 代表不再使用bean的默认ID(即类名首字母小写bookController,而是使用zhangjia)

      4.  测试类:

      public class Test {
          public static void main(String[] args) {
      //        初始化Spring的IOC容器
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
              BookService bookService = (BookService) context.getBean("bookService");
              bookService.getBookDao();
      
              BookController zhangjia = (BookController)context.getBean("zhangjia");
              zhangjia.getBookService();
              context.close();
      
          }
      }
      输出:
      bookDao = io.zhangjia.spring.dao.BookDao@59717824
      bookService = io.zhangjia.spring.service.BookService@146044d7

      四.  使用注解完成属性的自动注入

      《Spring:使用JdbcTemplate开发DAO》一文中,我们通过XML的方式完成了自动注入,除了使用XML的方式还可以使用注解来完成自动注意,还是以上面的例子为例,我们使用注解来完成上述例子中bookService和bookController的自动注入。

      使用注解来完成属性的自动注入非常简单,只需要将@Value修改为 @Autowired 即可:

      @Service
      public class BookService {
          @Autowired
          private BookDao bookDao;
          ....
      }
      
      
      @Controller("zhangjia")
      public class BookController {
          @Autowired
          private BookService bookService;
          ....
      }

      直接使用@Autowired存在一个问题,以BookController为例,如果我们的项目中没有BookService,则会触发异常,比如我们将BookService的@Service注解删除,此时再运行测试类,则会报以下异常:

      Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.zhangjia.spring.service.BookService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

      我们可以为Autowired设置required属性来选择是否必须注入

      • true:(默认的,注入失败会出现异常)

      • false:不强制注入,注入失败不会有异常

      将修改为:

      @Controller("zhangjia")
      public class BookController {
          @Autowired(required = false)
          private BookService bookService;
          ...
       }

      此时再次运行测试类,不会报任何异常


    • 0
    • 0
    • 0
    • 3.8k
    • 请登录之后再进行评论

      登录

      赞助本站

      • 支付宝
      • 微信
      • QQ

      感谢一直支持本站的所有人!

      单栏布局 侧栏位置: