目录
(3)注解@Resource(相当于@Autowired+@Qualifier)
<2>加载外部properties文件。(注解@PropertySource )
本篇博客的学习内容是基于博主前几篇博客的学习和总结。
一、简单spring项目(纯注解开发)环境搭建。
(1)Maven。spring-context依赖坐标。
- 在项目的pom文件中引入所需要的依赖坐标。
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.18</version> </dependency> </dependencies>
(2)service层。(使用注解@Service)
- BookService接口。
package com.fs.service; public interface BookService { /** * service层save方法 */ void save(); }
- BookServiceImpl实现类。
package com.fs.service.impl; import com.fs.dao.BookDao; import com.fs.service.BookService; import org.springframework.stereotype.Service; @Service public class BookServiceImpl implements BookService { //需将dao层对象注入到service层中 private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } @Override public void save() { System.out.println("book service save..."); bookDao.save(); } }
(3)dao层。(使用注解@Repository)
- BookDao接口。
package com.fs.dao; public interface BookDao { /** * dao层save方法 */ void save(); }
- BookDaoImpl实现类。
package com.fs.dao.impl; import com.fs.dao.BookDao; import org.springframework.stereotype.Repository; @Repository public class BookDaoImpl implements BookDao { @Override public void save() { System.out.println("book dao save..."); } }
(4)配置类。(SpringConfig)
- 使用注解@Configuration标明这是一个spring的配置类。(取代spring配置文件)
- 使用注解@ComponentScan让其自动扫描指定包下的类的注解。
package com.fs.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan({"com.fs.service","com.fs.dao"}) public class SpringConfig { }
(5)测试类。(AppForAnnotation)
- 因为在BookServiceImpl中没有成功注入BookDao实现类BookDaoImpl的对象。所以调用save()方法时会报错!
- 而本篇博客的学习就是使用注解完成自动装配(注入)。
package com.fs.test; import com.fs.config.SpringConfig; import com.fs.service.BookService; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class AppForAnnotation { public static void main(String[] args) { //加载配置类初始化容器对象 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); BookService bookService = context.getBean(BookService.class); bookService.save(); } }
- 如果是基于spring配置文件且使用对应的setter注入方式后调用save()方法不会报错!
二、spring注解开发——自动装配。
(1)注解@Autowired。
<1>数据层的单个实现时。
- 删除setter注入的代码片段。在需要注入的BookDao对象上使用注解@Autowired。
package com.fs.service.impl; import com.fs.dao.BookDao; import com.fs.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BookServiceImpl implements BookService { //需将dao层对象注入到service层中 @Autowired private BookDao bookDao; @Override public void save() { System.out.println("book service save..."); bookDao.save(); } }
- 运行结果如下。(成功注入!)
<2>数据层相同类型,但多个实现时。
- 这里再添加一个类BookDapImpl2实现接口BookDao。
package com.fs.dao.impl; import com.fs.dao.BookDao; import org.springframework.stereotype.Repository; @Repository public class BookDaoImpl2 implements BookDao { @Override public void save() { System.out.println("book dao save...2"); } }
- 运行测试类,查看程序运行的结果如下。
- 发现BookServiceImpl中也提示了相应的报错。
- 所以可以得出结论:注解@Autowired默认按照类型(byType)方式进行注入。
- 这种情况可以分别调整dao层实现类的注解@Repository("bookDao")、@Repository("bookDao2")。
- 但通常是:使用注解@Qualifier完成按名称(byName)注入!
<3>自动装配-注解@Autowired注意点。
- 自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据。因此无需提供对应的setter方法。
- 自动装配建议使用无参构造方法创建对象(默认)。如果不提供对应构造方法,请提供唯一的构造方法。
(2)注解@Qualifier。
- 使用注解@Qualifier注解开启指定名称装配bean。
- 注意:@Qualifier注解无法单独使用,必须配合@Autowired注解。
- 使用方法:在注解@Autowired的下方使用注解@Qualifier("指定名称?")。
- BookDaoImpl。
package com.fs.dao.impl; import com.fs.dao.BookDao; import org.springframework.stereotype.Repository; @Repository("bookDao") public class BookDaoImpl implements BookDao { @Override public void save() { System.out.println("book dao save..."); } }
- BookDaoImpl2。
package com.fs.dao.impl; import com.fs.dao.BookDao; import org.springframework.stereotype.Repository; @Repository("bookDao2") public class BookDaoImpl2 implements BookDao { @Override public void save() { System.out.println("book dao save...2"); } }
- BookServiceImpl。
package com.fs.service.impl; import com.fs.dao.BookDao; import com.fs.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @Service public class BookServiceImpl implements BookService { //需将dao层对象注入到service层中 @Autowired @Qualifier("bookDao") private BookDao bookDao; @Override public void save() { System.out.println("book service save..."); bookDao.save(); } }
- 分别修改注解@Qualifier所用的名称,查看运行结果。
(3)注解@Resource(相当于@Autowired+@Qualifier)
- 使用注解@Resource(name="?")完成指定名称的自动装配bean。
- 当然,注解@Resource默认可以不给参数(name),这时就相当于注解@Autowired。
- 使用注解@Resource(name="?")代替@Autowired+@Qualifier("?")。
package com.fs.service.impl; import com.fs.dao.BookDao; import com.fs.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class BookServiceImpl implements BookService { //需将dao层对象注入到service层中 @Resource(name = "bookDao") private BookDao bookDao; @Override public void save() { System.out.println("book service save..."); bookDao.save(); } }
- 程序测试的运行结果如下。
(4)注解@Value。(注入简单类型数据)
<1>修改dao层代码。(新增简单类型的成员变量)
- @使用注解@Value可以实现简单类型注入。
package com.fs.dao.impl; import com.fs.dao.BookDao; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; @Repository("bookDao") public class BookDaoImpl implements BookDao { @Value("zhangsan666") private String name; @Override public void save() { System.out.println("book dao save..."+name); } }
- 程序测试的运行结果如下。
<2>加载外部properties文件。(注解@PropertySource )
- 将上面的成员变量的值放在外部的properties文件中,这样就不会形成"硬编码"的情况。
- 在resources目录下新建jdbc.properties文件。
- jdbc.properties文件中写入name属性值。
- 在基于XML配置文件开发时,引入外部properties文件使用标签<properties>。
- 在spring的配置类中加载外部的properties文件使用注解@PropertySource("")。
package com.fs.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @ComponentScan({"com.fs.service","com.fs.dao"}) @PropertySource("jdbc.properties") public class SpringConfig { }
- 对应注解@Value的括号中使用${键名}完成值的注入。具体如下所示。
package com.fs.dao.impl; import com.fs.dao.BookDao; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; @Repository("bookDao") public class BookDaoImpl implements BookDao { @Value("${name}") private String name; @Override public void save() { System.out.println("book dao save..."+name); } }
<3>注解@PropertySource注意点如下。
- 加载多个外部properties文件时,格式:@PropertySource({properties1,properties2,properties3,...})。
- 注解@PropertySource不支持使用通配符"*"。如下举例不支持。
- 其次支持使用用法classpath:xxx.properties。(但也不支持使用"*")
package com.fs.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @Configuration @ComponentScan({"com.fs.service","com.fs.dao"}) @PropertySource("classpath:jdbc.properties") public class SpringConfig { }