赞
踩
本文总结自《spring揭秘》,作者王福强,非常棒的一本书,墙裂推荐;
1)spring自动绑定对象间依赖关系: 指的是不用明确指定每一个bean与被依赖bean之间的依赖关系,太繁琐; 而是通过一种约定方式来指定依赖关系,如通过名称,bean类型,构造器等约定方式来指定; 通过名称或类型等约定方式指定bean之间的依赖关系称自动绑定 ;
2)spring容器自动绑定对象间依赖关系的方式有2种,如下:
1)基于xml配置文件版本的自动绑定,自动绑定策略通过设置 beans元素的 default-autowire属性 或 bean元素的autowire属性来配置 ;
2)default-autowire属性值或autowire属性值的可选项:
3)自动绑定补充:
1)应用场景: 对于DDD领域驱动设计,其有4层,包括表现层,应用层,领域层,基础设施层;
表现层: 本文用main方法表示;
应用层: 本文用 appService 表示;采用构造器constructor绑定; 底层使用setter注入;
领域层: 本文用 DomainService 表示;采用byType绑定; 底层使用setter注入;
基础设置层:本文用dao表示;采用byName绑定, 有setter方法;
防腐层support: 在业务模型与技术模型之间,即应用层或领域层与基础设施层之间(**作用:**技术模型底层做改造,仅防腐层改动代码,上游的应用层与领域层不修改代码);
【AutoWireXmlConfMain】xml配置文件自动绑定main
public class AutoWireXmlConfMain {
public static void main(String[] args) {
ApplicationContext container = new ClassPathXmlApplicationContext("classpath:chapter06/beans0601autowirebasedxml.xml");
container.getBean(RoomBookAppService.class).book("基于xml配置文件的自动绑定房间01", "张三");
}
}
【beans0601autowirebasedxml.xml】 beans元素的default-autowire属性设置为byName, bean元素的autowire属性设置为 constructor,byType, byName ;
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName">
<bean id="roomBookAppService" class="com.tom.springnote.chapter05.chapter0504.RoomBookAppService" autowire="constructor" />
<bean id="roomBookDomainService" class="com.tom.springnote.chapter05.chapter0504.RoomBookDomainService" autowire="byType" />
<bean id="roomBookSupportImpl" class="com.tom.springnote.chapter05.chapter0504.RoomBookSupportImpl" autowire="byName" />
<bean id="roomBookDAO" class="com.tom.springnote.chapter05.chapter0504.RoomBookDAO" />
</beans>
【RoomBookAppService】应用层, 通过构造器绑定
public class RoomBookAppService {
private RoomBookDomainService roomBookDomainService;
public RoomBookAppService(RoomBookDomainService roomBookDomainService) {
this.roomBookDomainService = roomBookDomainService;
}
public void book(String roomId, String customer) {
roomBookDomainService.book(roomId, customer);
}
}
【RoomBookDomainService】领域层,通过byType绑定,必须要有setter方法;( 属性名称叫roomBookSupport,但xml中配置的bean名称为roomBookSupportImpl,通过byName无法绑定 )
public class RoomBookDomainService {
private IRoomBookSupport roomBookSupport;
public void book(String roomId, String customer) {
roomBookSupport.saveRoomBookInf(roomId, customer);
}
public void setRoomBookSupport(IRoomBookSupport roomBookSupport) {
this.roomBookSupport = roomBookSupport;
}
}
【IRoomBookSupport】防腐层接口
public interface IRoomBookSupport {
void saveRoomBookInf(String roomId, String customer);
}
【RoomBookSupportImpl】防腐层实现类 ; 通过byName绑定 ;必须要有setter方法 ;
public class RoomBookSupportImpl implements IRoomBookSupport {
private RoomBookDAO roomBookDAO;
@Override
public void saveRoomBookInf(String roomId, String customer) {
roomBookDAO.insertRoomBook(roomId, customer);
}
public void setRoomBookDAO(RoomBookDAO roomBookDAO) {
this.roomBookDAO = roomBookDAO;
}
}
【RoomBookDAO】基础设施层; 无需绑定对象依赖关系(因为没有依赖),仅注册bean到spring容器即可;
public class RoomBookDAO {
public void insertRoomBook(String roomId, String customer) {
System.out.printf("RoomBookDAO: 插入订房信息成功:roomId=[%s], customer=[%s]\n", roomId, customer);
}
}
【打印日志】
RoomBookDAO: 插入订房信息成功:roomId=[基于xml配置文件的自动绑定房间01], customer=[张三]
1)@Autowired是基于注解版本的自动绑定的核心注解, spring容器根据@Autowired标注的位置为当前类注入依赖;
2)@Autowired注解的标注位置:
3)案例场景: 房间预订服务;
【AutoWireBasedAnnotationMain】基于注解的自动绑定main
public class AutoWireBasedAnnotationMain {
public static void main(String[] args) {
ApplicationContext container = new ClassPathXmlApplicationContext("classpath:chapter06/beans0601autowirebasedannotation.xml");
container.getBean(AnnotationBookAppService.class).book("基于注解的自动绑定房间01", "张三");
}
}
【beans0601autowirebasedannotation.xml】 若使用 @Autowired,必须注册 AutowiredAnnotationBeanPostProcessor
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 注册AutowiredAnnotationBeanPostProcessor, 用于检查是否有@Autowired标注的位置以便注入依赖 【若使用 @Autowired,必须注册该BeanPostProcessor】 --> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> <!-- 注册bean,依赖关系由 @Autowired 标注,spring容器根据标注位置绑定依赖 --> <bean id="roomBookAppService" class="com.tom.springnote.chapter06.autowirebaseannotation.RoomBookAppService" /> <bean id="roomBookDomainService" class="com.tom.springnote.chapter06.autowirebaseannotation.RoomBookDomainService" /> <bean id="roomBookSupportImpl" class="com.tom.springnote.chapter06.autowirebaseannotation.RoomBookSupportImpl" /> <bean id="roomDAO" class="com.tom.springnote.chapter06.autowirebaseannotation.RoomDAO" /> <bean id="hotelDAO" class="com.tom.springnote.chapter06.autowirebaseannotation.HotelDAO" /> </beans>
【RoomBookAppService】 应用层:@Autowired标注构造器 (byType的自动绑定 )
public class RoomBookAppService {
private RoomBookDomainService bookDomainService;
@Autowired
public RoomBookAppService(RoomBookDomainService bookDomainService) {
this.bookDomainService = bookDomainService;
}
public void book(String roomId, String customer) {
bookDomainService.book(roomId, customer);
}
}
【RoomBookDomainService】 领域层: @Autowired标注属性 (byType的自动绑定 )
public class RoomBookDomainService {
@Autowired
private IRoomBookSupport bookSupport;
public void book(String roomId, String customer) {
bookSupport.saveRoomBookInf(roomId, customer);
}
public void setBookSupport(IRoomBookSupport bookSupport) {
this.bookSupport = bookSupport;
}
}
【IRoomBookSupport】防腐层接口
public interface IRoomBookSupport {
void saveRoomBookInf(String roomId, String customer);
}
【RoomBookSupportImpl】防腐层:.@Autowired标注setter方法 ,标注普通方法 (byType的自动绑定 )
public class RoomBookSupportImpl implements IRoomBookSupport { private RoomDAO bookDAO; private HotelDAO hotelDAO; @Override public void saveRoomBookInf(String roomId, String customer) { if (!hotelDAO.IfAuthLegal(customer)) { System.out.println("权限校验失败"); return; } System.out.println("权限校验成功"); bookDAO.insertRoomBook(roomId, customer); } @Autowired public void setBookDAO(RoomDAO bookDAO) { this.bookDAO = bookDAO; } @Autowired public void injectHotelDAO(HotelDAO hotelDAO) { this.hotelDAO = hotelDAO; } }
【HotelDAO】
public class HotelDAO {
public boolean IfAuthLegal(String customer) {
System.out.printf("HotelDAO#IfAuthLegal(): [%s]权限校验合法", customer);
return true;
}
}
【RoomDAO】
public class RoomDAO {
public void insertRoomBook(String roomId, String customer) {
System.out.printf("RoomDAO#insertRoomBook(): 插入订房信息成功:roomId=[%s], customer=[%s]\n", roomId, customer);
}
}
【打印日志】
HotelDAO#IfAuthLegal(): [张三]权限校验合法权限校验成功
RoomDAO#insertRoomBook(): 插入订房信息成功:roomId=[基于注解的自动绑定房间01], customer=[张三]
1)背景: 若一个接口有2个或多个实现类,如实例A与B ; 而@Autowired 注解是通过byType自动绑定,无法确认注入实例A还是实例B;
2)解决方法: 引入 @Qualifier注解, 解决@Autowired无法注入有多个类型匹配的bean的问题;
业务场景: 酒店预订助手接口有2个实现类, 包括 万达酒店预定助手实现类, 希尔顿酒店预定助手实现类; 通过 @Qualifier注解指定bean名称并注入name匹配的bean;
【AutowireQualifierAnnotationMain】基于@Autowired与@Qualifier注解自动绑定main
public class AutowireQualifierAnnotationMain {
public static void main(String[] args) {
ApplicationContext container = new ClassPathXmlApplicationContext("classpath:chapter06/beans0601autowirequlifierannotation.xml");
container.getBean(AutowireQualifierBookAppService.class).book("@Autowired与@Qualifier注解的自动绑定01", "张三");
}
}
【beans0601autowirequlifierannotation.xml】 新增 <context:annotation-config/> 元素, 以激活 @Autowired 和 @Qualifier 注解
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <!-- 注册 AutowiredAnnotationBeanPostProcessor, 用于检查是否有@Autowired标注的位置以便注入依赖 AutowiredAnnotationBeanPostProcessor 激活 @Autowired 注解 --> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> <!-- 注册bean --> <bean id="bookAppService" class="com.tom.springnote.chapter06.autowiredqualifierannotation.AutowireQualifierBookAppService" /> <bean id="bookDomainService" class="com.tom.springnote.chapter06.autowiredqualifierannotation.AutowireQualifierBookDomainService" /> <bean id="bookDomainService2" class="com.tom.springnote.chapter06.autowiredqualifierannotation.AutowireQualifierBookDomainService" /> <bean id="hiltonRoomBookSupportImpl" class="com.tom.springnote.chapter06.autowiredqualifierannotation.HiltonRoomBookSupportImpl" /> <bean id="wandaRoomBookSupportImpl" class="com.tom.springnote.chapter06.autowiredqualifierannotation.WandaRoomBookSupportImpl" /> <bean id="roomDAO" class="com.tom.springnote.chapter06.autowiredqualifierannotation.RoomDAO" /> <bean id="roomDAO2" class="com.tom.springnote.chapter06.autowiredqualifierannotation.RoomDAO" /> <bean id="hotelDAO" class="com.tom.springnote.chapter06.autowiredqualifierannotation.HotelDAO" /> <bean id="hotelDAO2" class="com.tom.springnote.chapter06.autowiredqualifierannotation.HotelDAO" /> </beans>
【AutowireQualifierBookAppService】 ( 构造器新增 @Quailfier注解 )
public class AutowireQualifierBookAppService {
private AutowireQualifierBookDomainService annotationBookDomainService;
@Autowired
public AutowireQualifierBookAppService(@Qualifier("bookDomainService2") AutowireQualifierBookDomainService bookDomainService) {
this.annotationBookDomainService = bookDomainService;
}
public void book(String roomId, String customer) {
annotationBookDomainService.book(roomId, customer);
}
}
【AutowireQualifierBookDomainService】( 属性上新增 @Quailfier注解 )
public class AutowireQualifierBookDomainService {
@Autowired
@Qualifier("hiltonRoomBookSupportImpl")
private IAutowireQualifierBookSupport bookSupport;
public void book(String roomId, String customer) {
bookSupport.saveRoomBookInf(roomId, customer);
}
}
【IAutowireQualifierBookSupport】
public interface IAutowireQualifierBookSupport {
void saveRoomBookInf(String roomId, String customer);
}
【HiltonRoomBookSupportImpl】 ( setter方法与普通方法上新增 @Quailfier注解 )
public class HiltonRoomBookSupportImpl implements IAutowireQualifierBookSupport { private RoomDAO bookDAO; private HotelDAO hotelDAO; @Override public void saveRoomBookInf(String roomId, String customer) { System.out.println("希尔顿酒店预订助手"); if (!hotelDAO.IfAuthLegal(customer)) { System.out.println("权限校验失败"); return; } System.out.println("权限校验成功"); bookDAO.insertRoomBook(roomId, customer); } @Autowired public void setBookDAO(@Qualifier("roomDAO") RoomDAO bookDAO) { this.bookDAO = bookDAO; } @Autowired public void injectHotelDAO(@Qualifier("hotelDAO") HotelDAO hotelDAO) { this.hotelDAO = hotelDAO; } }
【WandaRoomBookSupportImpl】 ( setter方法与普通方法上新增 @Quailfier注解 )
public class WandaRoomBookSupportImpl implements IAutowireQualifierBookSupport { private RoomDAO bookDAO; private HotelDAO hotelDAO; @Override public void saveRoomBookInf(String roomId, String customer) { System.out.println("万达酒店预订助手"); if (!hotelDAO.IfAuthLegal(customer)) { System.out.println("权限校验失败"); return; } System.out.println("权限校验成功"); bookDAO.insertRoomBook(roomId, customer); } @Autowired public void setBookDAO(@Qualifier("roomDAO2") RoomDAO bookDAO) { this.bookDAO = bookDAO; } @Autowired public void injectHotelDAO(@Qualifier("hotelDAO2") HotelDAO hotelDAO) { this.hotelDAO = hotelDAO; } }
【打印日志】
希尔顿酒店预订助手
HotelDAO#IfAuthLegal(): [张三]权限校验合法
权限校验成功
RoomDAO#insertRoomBook(): 插入订房信息成功:roomId=[基于注解的自动绑定房间01], customer=[张三]
@Primary注解: 标注的类的bean实例化后, 若该类下有多个实例化的bean,则优先使用 被Primary标注的那个bean;
【PdfFileReader】FileReader子类1
package basic.ioc.wiring.finetune;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Primary
@Component
public class PdfFileReader implements FileReader {
@Override
public void print() {
System.out.println("Inside PdfFileReader");
}
}
【WordFileReader】FileReader子类2
package basic.ioc.wiring.finetune;
import org.springframework.stereotype.Component;
@Component
public class WordFileReader implements FileReader {
@Override
public void print() {
System.out.println("Inside WordFileReader");
}
}
【FineTuneAutowiring】Primary注解测试案例入口
package basic.ioc.wiring.finetune; import org.junit.Assert; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; @SpringJUnitConfig(ConfigWiring.class) public class FineTuneAutowiring { @Autowired private FileReader fileReader; @Test public void testFileReader() { Assert.assertNotNull(fileReader); Assert.assertEquals(fileReader.getClass(), PdfFileReader.class); } }
因为 PdfFileReader 被@Primary注解标注, 所以业务bean#FineTuneAutowiring通过 @Autowired自动绑定 FileReader实例时,优先选择PdfFileReader示例进行绑定;
1)<context:annotation-config /> 可以激活多个注解以便在class中被探测到: 激活的注解清单如下:
或者你也可以选择注入这些注解对应的BeanPostProcessor ;
2)context:annotation-config 注册的BeanPostProcessor清单如下: 参见: https://docs.spring.io/spring-framework/reference/core/beans/annotation-config.html
3) 我们可以这样理解:因为context:annotation-config 注册了多个BeanPostProcessor到spring容器,这些BeanPostProcessor可以扫描注解标注的位置,以此自动绑定相应依赖注入;即 注册BeanPostProcessor,间接激活了自动绑定的注解 ;
4)所以 beans0601autowirequlifierannotation.xml中可以删除 AutowiredAnnotationBeanPostProcessor 这个BeanPostProcessor的注入配置;因为 context:annotation-config 激活了对应的BeanPostProcessor;
删除AutowiredAnnotationBeanPostProcessor注入配置后xml如下 :
【beans0601autowirequlifierannotation.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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <!-- 注册bean --> <bean id="bookAppService" class="com.tom.springnote.chapter06.autowiredqualifierannotation.AutowireQualifierBookAppService" /> <bean id="bookDomainService" class="com.tom.springnote.chapter06.autowiredqualifierannotation.AutowireQualifierBookDomainService" /> <bean id="bookDomainService2" class="com.tom.springnote.chapter06.autowiredqualifierannotation.AutowireQualifierBookDomainService" /> <bean id="hiltonRoomBookSupportImpl" class="com.tom.springnote.chapter06.autowiredqualifierannotation.HiltonRoomBookSupportImpl" /> <bean id="wandaRoomBookSupportImpl" class="com.tom.springnote.chapter06.autowiredqualifierannotation.WandaRoomBookSupportImpl" /> <bean id="roomDAO" class="com.tom.springnote.chapter06.autowiredqualifierannotation.RoomDAO" /> <bean id="roomDAO2" class="com.tom.springnote.chapter06.autowiredqualifierannotation.RoomDAO" /> <bean id="hotelDAO" class="com.tom.springnote.chapter06.autowiredqualifierannotation.HotelDAO" /> <bean id="hotelDAO2" class="com.tom.springnote.chapter06.autowiredqualifierannotation.HotelDAO" /> </beans>
【补充】 如果xml文件中只注入 AutowiredAnnotationBeanPostProcessor , 而不引入 <context:annotation-config />元素, 则无法激活 @Qualifier注解。 这会导致spring自动绑定依赖关系时,若发现同一个类有多个bean,则抛出异常 【No qualifying bean of type ‘XXX’ available: expected single matching bean but found 2: XXX1, XXX2】。
1) jsr250,即第250号java规范请求,其提供的注解包括 @Resource, @PostConstruct , @PreDestory ;
【Jsr250AnnotationAutowireMain】JSR250注解自动装配main入口
public class Jsr250AnnotationAutowireMain {
public static void main(String[] args) {
String[] locations = {"classpath:chapter06/beans0601autowirequlifierannotation.xml"
, "classpath:chapter06/beans0601jsr250annotation.xml"};
ClassPathXmlApplicationContext container = new ClassPathXmlApplicationContext(locations);
// 若有bean销毁前执行回调,则需要注册关闭钩子回调
container.registerShutdownHook();
container.getBean(Jsr250AnnotationBookAppService.class).book("JSR250#@Resource注解的自动绑定01", "张三");
System.out.println("容器关闭");
}
}
【Jsr250AnnotationBookAppService】JSR250注解@Resource标注bean以便自动绑定依赖关系
public class Jsr250AnnotationBookAppService { @Resource(name = "bookDomainService2") private AutowireQualifierBookDomainService annotationBookDomainService; public Jsr250AnnotationBookAppService() { System.out.println("Jsr250AnnotationBookAppService 构造器"); } public void book(String roomId, String customer) { annotationBookDomainService.book(roomId, customer); } @PostConstruct public void afterInstance() { System.out.println("@PostConstruct注解标注的方法,实例化之后执行"); } @PreDestroy public void destory() { System.out.println("@PreDestroy注解标注的方法,bean销毁前执行"); } }
【打印日志】
Jsr250AnnotationBookAppService 构造器
@PostConstruct注解标注的方法,实例化之后执行
希尔顿酒店预订助手
HotelDAO#IfAuthLegal(): [张三]权限校验合法
权限校验成功
RoomDAO#insertRoomBook(): 插入订房信息成功:roomId=[JSR250#@Resource注解的自动绑定01], customer=[张三]
容器关闭
@PreDestroy注解标注的方法,bean销毁前执行
【@Resource注解作用总结】
@Resource注解可以替代 @Autowired 与 @Qualilfier这2个注解结合的功能,即根据beanName到spring容器中查找匹配的bean,并注入依赖关系到当前bean(如Jsr250AnnotationBookAppService);
1) @PostConstruct: bean实例化后被调用(构造器执行后被调用);
2)@PreDestroy: bean销毁前被调用;
补充: 代码示例参见 Jsr250AnnotationBookAppService ;
1)背景: 2.2 与 2.3的代码示例中, xml配置文件仅注册bean,不管理bean的依赖关系; 其依赖关系通过注解来管理; 即需要编写xml配置与注解;当bean比较多的时候,开发xml配置文件比较繁琐;
2)解决方法: 使用 classpath-scanning 扫描给定路径的package;
3)classpath-scanning组件扫描功能,通过在xml文件配置 <context:component-scan> 来开启;
4)补充: <context:component-scan> 元素,可以新增属性 include-filter 和 exclude-filter 分别包含和排除某些package ;
【ComponentScanMain】main入口
public class ComponentScanMain {
public static void main(String[] args) {
ClassPathXmlApplicationContext container = new ClassPathXmlApplicationContext("classpath:chapter06/beans0601componentscan.xml");
container.getBean(ComponentScanAppService.class).scan();
}
}
【beans0601componentscan.xml】 配置了 <context:annotation-config/> 元素, <context:component-scan> 元素 ;
其中,当需要扫描多个包时,用逗号分割;
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 注册5个BeanPostProcessor,间接激活多个自动绑定注解及JSR250注解,包括 @Autowired, @Qualiifer, @Resource, @PostConstruct, @PreDestory -->
<context:annotation-config/>
<!-- 开启组件扫描,无需手工在xml配置文件注册每个bean,间接激活多个component注解,包括 @Componenet, @Repository ,@Service, @Controller -->
<context:component-scan base-package="com.tom.springnote.chapter06.componentscan,com.tom.springnote.chapter06.componentscan2" />
</beans>
【ComponentScanAppService】 ( 使用 @Service注解 )
@Service
public class ComponentScanAppService {
@Autowired
private ComponentScanDomainService scanComponentDomainService;
public void scan() {
scanComponentDomainService.scan();
}
}
【ComponentScanDomainService】( 使用 @Service注解 )
@Service
public class ComponentScanDomainService {
@Autowired
@Qualifier("hiltonComponenetScanSupportImpl")
private IComponentScanSupport componentScanSupport;
public void scan() {
componentScanSupport.scan();
}
}
【IComponentScanSupport】
public interface IComponentScanSupport {
void scan();
}
【HiltonComponenetScanSupportImpl】 ( 使用 @Component注解 )
@Component("hiltonComponenetScanSupportImpl")
public class HiltonComponenetScanSupportImpl implements IComponentScanSupport {
@Autowired
private ComponentScanDAO scanComponentDAO;
@Override
public void scan() {
System.out.println("希尔顿组件扫描助手");
scanComponentDAO.scan();
}
}
【WandaComponenetScanSupportImpl】 ( 使用 @Component注解 )
@Component("wandaComponenetScanSupportImpl")
public class WandaComponenetScanSupportImpl implements IComponentScanSupport {
@Autowired
private ComponentScanDAO scanComponentDAO;
@Override
public void scan() {
System.out.println("万达组件扫描助手");
scanComponentDAO.scan();
}
}
【ComponentScanDAO】 ( 使用 @Repository注解 )
@Repository
public class ComponentScanDAO {
public void scan() {
System.out.println("ScanComponentDAO#scan():扫描完成");
}
}
【打印日志】
希尔顿组件扫描助手
ScanComponentDAO#scan():扫描完成
1)本文描述了2种自动绑定依赖关系的方式, 包括xml配置文件版本的自动绑定,注解版本的自动绑定;
2)问题:能否仅使用注解实现自动绑定; 答案是否;
1)JSR,Java Specification Request, 即 java规范请求: 是 Java 平台提议和最终规范的实际描述。任何时候都有大量 JSR 正在通过审查和批准流程。 JSR250表示第250号java规范请求; 参见 https://jcp.org/en/jsr/overview ;JSR清单,参见:https://jcp.org/en/jsr/all
简单理解, 开发者自行开发了api,把api封装到JSR并报送给java社区;审批通过后,以JSR形式发布api;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。