内容

  • 声明bean
  • 构造器注入和Setter方法注入
  • 装配Bean
  • 控制bean的创建和销毁

关键词

  • 装配(wiring)
  • 组件扫描(component scanning)
  • 自动装配(AutoWiring)

2.1 Spring配置的可选方案

Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系,而我们就是需要控制Spring要创建哪些Bean并且如何将其装配在一起。

Spring提供了三种装配机制:

  1. 在XML中显式配置
  2. 在Java中进行显式配置(JavaConfig)
  3. 隐式的bean发现机制和自动装配

web开发,提供三个@Component注解衍生注解(功能一样)取代

@Repository: Dao层

@Service: Service层

@Controller:web层

依赖注入:(给私有字段,或者setter方法)

  • 普通值:@Value("")
  • 引用值:
      1. 按照类型注入:@Autowired
      1. 按照名称注入
        1. @Autowired+@Qualifier("名称")
        1. @Resource("名称")

2.2 自动化装配bean

自动化装配实现

  1. 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean
  2. 自动装配(autowiring):Spring自动满足bean之间的依赖。

组件扫描和自动装配在一起会显示出强大的威力,并将显式配置降低到最少。

// java接口
package Book; public interface PutBook {
void put();
}
// Java接口实现类
package Book;
import org.springframework.stereotype.Component; @Component
public class SetBook implements PutBook {
private String book_name = "Harry Potter";
private String author = "JK";
public void put() {
System.out.println("book_name"+book_name+"author:"+author);
}
}

注意第二段代码使用了@Component,这个注解将该类作为了组件类,并告知Spring为该类创建一个bean。但是该组件扫描默认不启用,需要显式配置Spring,从而命令它去寻找带有@Component的注解的类,并为其创建bean。

// 启用组件扫描类
package Book; import org.springframework.context.annotation.componentScan;
import org.springframework.context.annotation.Configuration; @Configuration
@ComponentScan
public class bookConfig { }

ComponentScan默认会扫描鱼配置类相同的包,从而发现带有Component注解的类,并在Spring中自动为其创建一个bean

// 测试代码
package com.baidu.hankanvideo.book; import static org.junit.Assert.*; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.ContextConfiguration; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = BookConfig.class)
public class BookTest { @Autowired
private PutBook putBook; @Test
public void bookIsNotBeNull() {
assertNotNull(putBook);
}
}

以上为单元测试代码,通过检查PutBook属性是否为null,不为null则证明可以发现并注入。

2.2.1 为组件扫描的bean命名

Spring应用上下文中所有的bean都会给定一个ID。如果不指定则会根据类名来指定一个ID。

@Component("lonelyHearts")
public class SetBook implements PutBook { }

2.2.2 设置组件扫描的基础包

目前ComponentScan扫描包的范围会以配置类所在的包作为基础包(base package)进行扫描,所以指定包和多个包的配置如下。

// 一、单个包
@Configuration
@ComponentScan("model")
或者
@ComponentScan(basePackages="model") // 二、多个包
@Configuration
@ComponentScan(basePackages={"model","service"}) // 以上方法简单但是不够安全,如果包重构或者类被放到其他包,就会出现问题。所以指定类或者接口
@Configuration
@ComponentScan(basePackageClasses={Book.class,PutBook.class})

2.2.3 通过为bean添加注解实现自动装配

自动装配就是让Spring自动满足bean依赖的一种方法,在满足依赖的过程中描绘在Spring应用上下文中寻找匹配某个bean需求的其他bean。为了声明要进行的自动装配,在Spring中使用@AutoWired。

// Java接口实现类
package Book;
import org.springframework.stereotype.Component; @Component
public class SetBook implements PutBook {
private String book_name = "Harry Potter";
private String author = "JK"; @AutoWired
public BookStore(PutBook putBook) {
this.book = putBook;
} public void put() {
System.out.println("book_name"+book_name+"author:"+author);
}
}

总结:

  • @AutoWired可以用在构造器上
  • @AutoWired可以用在属性的Setter方法上
  • 还可以用在类的任何方法上

2.3 通过Java代码装配bean(显式装配)

将第三方库中的组件装配到应用中,就需要使用显式配置的方式,而上面通过组件扫描和自动装配的自动化配置是不可用的。

JavaConfig是配置代码,意味着它不应该包含任何业务逻辑,JavaConfig也不应该侵入到业务逻辑代码中。因此常常会将JavaConfig放到单独的包中,使其与其他的应用程序逻辑分离开来。

2.3.1 创建配置类

// 启用组件扫描类
package Book; import org.springframework.context.annotation.Configuration; @Configuration
public class bookConfig { }

单单只有@Configuration注解,但是缺少了上面的ComponentScan注解就会失效。

那么显式配置怎么做呢?

2.3.2 声明简单的bean

// 启用组件扫描类
package Book; import org.springframework.context.annotation.Configuration; @Configuration
public class bookConfig { // 新增一个方法注册一个Bean
@Bean
public CompactDisc sgtPeppers() {
return new SgtPeppers();
} }

@Bean 注解会告诉Spring这个方法将返回一个对象,该对象要注册为Spring应用上下文中的bean。方法体中包含最终产生bean实例的逻辑。

2.3.3 借助JavaConfig实现注入

package soundsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class CDPlayerConfig { @Bean
public CompactDisc compactDisc() {
return new SgtPeppers();
} @Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
return new CDPlayer(compactDisc);
} }

cdPlayer()方法请求一个CompactDisc作为参数。当Spring调用cdPlayer()创建CDPlayerbean的时候,它会自动装配一个CompactDisc到配置方法中。然后方法体就可以按照合适的方式使用它。这种方法可以不需引用CompactDisc的@Bean的方法。

2.4 总结

Spring框架的核心是Spring容器,容器负责管理应用中组件的生命周期,它会创建这些组件并保证他们的依赖能够得到满足,保证组件完成预定的任务。

写了一个小例子


package com.example.springlearn.testDI; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller; // 表明这是一个Controller注解,等价与Component
@Controller
public class BookController {
// 自动注入并指定ID
@Autowired
@Qualifier("bsId")
private BookService bookService; public void showBook() {
bookService.saveBook();
}
}
// 接口
package com.example.springlearn.testDI; import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service; public interface BookService { public void saveBook();
}
// 接口的实现类
package com.example.springlearn.testDI; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; @Service("bsId")
public class BookServiceImpl implements BookService { // 以前
// private BookDao bookDao = new BookDaoImpl()
private BookDao bookDao;
// 注入了Dao层
@Autowired
@Qualifier(value = "BookId")
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
} @Override
public void saveBook() {
this.bookDao.addBook();
}
}
package com.example.springlearn.testDI;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Repository; // Dao层接口
public interface BookDao { public void addBook();
}
package com.example.springlearn.testDI;

import org.springframework.stereotype.Repository;

// Dao层实现类,并用Repository注册
@Repository("BookId")
public class BookDaoImpl implements BookDao { @Override
public void addBook() {
System.out.println("add a book");
}
}

// 写了一个测试类
package com.example.springlearn; import com.example.springlearn.testDI.BookController;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class TestCarAspect { @Autowired
private BookController bookController; @Test
public void testCar() {
bookController.showBook(); }
}

最新文章

  1. python备忘
  2. 【Python】[函数] 函数的参数与递归函数
  3. ERROR 1130 (HY000):Host'localhost'解决方法
  4. c++中string类型用下标初始化后str.size()为0 输出string值为空
  5. CodeForces - 407A
  6. 代码管理工具TortoiseSVN
  7. 持续集成之Jenkins(坏老头)
  8. CarDAQ-Plus
  9. [置顶] 在js中如何实现方法重载?以及函数的参数问题
  10. 序列化为XML
  11. C# 通过smtp服务器进行邮件发送 MailHelper
  12. Tomcat 对 HTTP 协议的实现(上)
  13. 记录心得-IntelliJ iDea 创建一个maven管理的的javaweb项目
  14. [Java 泥水匠] Java Components 之一:Java String (肯定有你不懂的)
  15. P2877 [USACO07JAN]牛校Cow School(01分数规划+决策单调性分治)
  16. Luogu P2597 [ZJOI2012]灾难
  17. (GoRails) Form对象设计风格: 用自建的Model来对参数进行操作。
  18. anu - controlledComponent
  19. jp@gc - Stepping Thread Group 字段说明
  20. write solid code Chapter 2 练习题4 的解答与扩展

热门文章

  1. 图论--树的重心(DFS) 模板
  2. CentOS启用iptables防火墙
  3. vue获取当前时间 实时刷新
  4. TestNG测试用例重跑详解及实践优化
  5. [蓝桥杯2018初赛]小朋友崇拜圈(dfs找环)
  6. JVM系列-2、JVM内存结构
  7. ssm整合后打印日志查看执行sql语句
  8. word 小技巧 方框中 打 对勾
  9. Spring官网阅读(八)容器的扩展点(三)(BeanPostProcessor)
  10. 使用EF Code First生成模型,如何让时间字段由数据库自动生成