三种XML管理、创建bean的方式:Spring Ioc是Spring公司对“控制反转”思想的实现,运用xml来管理和创建bean
基于构造方法实例对象。
基于静态工厂实例化对象。
基于工厂实例方法实例化对象。
实体类
package pers.thc.spring.IoC.entity;
public class Apple {
private String title;
private String color;
private String origin;
public Apple(){}
public Apple(String title, String color, String origin) {
this.title = title;
this.color = color;
this.origin = origin;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
@Override
public String toString() {
return "Apple{" +
"title='" + title + ''' +
", color='" + color + ''' +
", origin='" + origin + ''' +
'}';
}
}
package pers.thc.spring.IoC.entity;
public class Child {
private String name;
private Apple apple;
public Child(){}
public Child(String name, Apple apple) {
this.name = name;
this.apple = apple;
}
@Override
public String toString() {
return "Child{" +
"name='" + name + ''' +
", apple=" + apple +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Apple getApple() {
return apple;
}
public void setApple(Apple apple) {
this.apple = apple;
}
}
静态工厂类
package pers.thc.spring.IoC.factory;
import pers.thc.spring.IoC.entity.Apple;
public class AppleFactory {
public static Apple createSweetApple(){
Apple apple = new Apple("红富士", "深红", "欧洲");
return apple;
}
}
实例工厂类
package pers.thc.spring.IoC.factory;
import pers.thc.spring.IoC.entity.Apple;
public class AppleFactoryInstance {
public Apple createSweetApple(){
Apple apple = new Apple("红富士", "深红", "欧洲");
return apple;
}
}
applicationContext.xml
Application类
package pers.thc.spring.IoC;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pers.thc.spring.IoC.entity.Apple;
import pers.thc.spring.IoC.entity.Child;
public class SpringApplication {
public static void main(String[] args) {
String configLocations[]=new String[]{
"classpath:applicationContext.xml", "classpath:applicationContext1.xml"};
//应用上下文加载顺序与字符串先后顺序有关
//启动IoC容器
// ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
//利用getBean来获取相应的实例对象
// Apple sweetApple = (Apple)context.getBean("sweetApple");
Apple sweetApple = context.getBean("sweetApple", Apple.class);//由于sweetApple在两个配置文件中都有,故后加载的配置文件中的sweetApple会覆盖掉先加载配置文件中的sweetApple
Child Lily = context.getBean("Lily", Child.class);
Child lily = context.getBean("lily", Child.class);//通过name标签可以设置多个bean标识,此处用lily标识获取实例对象
Apple apple = context.getBean("pers.thc.spring.IoC.entity.Apple", Apple.class);//若bean没有id、name标签,则通过完整类名获取实例对象
Apple apple1 = context.getBean("apple1", Apple.class);
Apple apple2 = context.getBean("apple2", Apple.class);
Apple apple3 = context.getBean("apple3", Apple.class);
Apple apple4 = context.getBean("apple4", Apple.class);
System.out.println(sweetApple);
System.out.println(Lily);
System.out.println(lily);
System.out.println(apple);
System.out.println(apple1);
System.out.println(apple2);
System.out.println(apple3);
System.out.println(apple4);
}
}
路径表达式:
classpath:config.xml 扫描classpath根路径(不包含jar)的config.xml
classpath:pers/thc/config.xml 扫描classpath下(不包含jar)pers.thc包中的config.xml
classpath*:pers/thc/config.xml 扫描classpath下(包含jar)pers.thc包中的config.xml
classpath:config-*.xml 扫描classpath根路径下所有一config-开头的XML文件
classpath:persconfig.xml 扫描pers包下(包含任何子包)的config.xml file:c/:config.xml 扫描c盘根路径config.xml
setter注入对象(property)
构造方法注入对象(constructor-arg)
bookshop 利用不同的配置文件,约定好bean的id,建立依赖关系(service的parent context为dao),实现分工合作。 其次,利用IoC容器还可以实现对象之间的解耦,当dao层修改实现细节时,秩序保证bean的id不变,service层不需要进行任何改变。
注入集合对象:通过“公司资产配置清单”案例学习集合类型动态注入
公司实体类
package pers.thc.spring.IoC.companyProperties.entity;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class Company {
private List rooms;
private Map computers;
private Properties info;
@Override
public String toString() {
return "Company{" +
"rooms=" + rooms +
", computers=" + computers +
", info=" + info +
'}';
}
public List getRooms() {
return rooms;
}
public void setRooms(List rooms) {
this.rooms = rooms;
}
public Map getComputers() {
return computers;
}
public void setComputers(Map computers) {
this.computers = computers;
}
public Properties getInfo() {
return info;
}
public void setInfo(Properties info) {
this.info = info;
}
}
电脑实体类
package pers.thc.spring.IoC.companyProperties.entity;
public class Computer {
private String brand;
private String type;
private String sn;
private Float price;
public Computer() {
}
public Computer(String brand, String type, String sn, Float price) {
this.brand = brand;
this.type = type;
this.sn = sn;
this.price = price;
}
@Override
public String toString() {
return "Computer{" +
"brand='" + brand + ''' +
", type='" + type + ''' +
", sn='" + sn + ''' +
", price=" + price +
'}';
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
}
applicationContext.xml
2001-总裁办 2003-总经理办公室 2010-研发部会议室 0772-3626316 广西省柳州市城中区八一路XX路XX栋XXXX室 http://www.xxx.com
Application类
package pers.thc.spring.IoC.companyProperties;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pers.thc.spring.IoC.companyProperties.entity.Company;
import pers.thc.spring.IoC.companyProperties.entity.Computer;
public class CompanyPropertiesApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext-company-properties.xml");
Company company = context.getBean("company", Company.class);
System.out.println(company);
//获取容器内所有beanId数组
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
Computer computer = context.getBean("pers.thc.spring.IoC.companyProperties.entity.Computer#1", Computer.class);
System.out.println(computer);//获取匿名bean的方法-2,通过类名全称#序号来获取相应的bean对象。序号为0,1,2……,按applicationContext.xml中的顺序递推
}
}
bean scope属性:
bean scope属性用于决定对象何时被创建与作用范围
bean scope配置将影响容器内对象的数量
默认情况下bean会在IoC容器创建后自动实例化,全局唯一
singleton 单例(默认值),每一个容器有且只有唯一的实例,实例会被全局共享。单例多线程,但存在线程安全风险。 singleton线程安全问题,a=2(用户1)a.setNum(1)->a对象num=1,(用户2)sout(a.getNum())->本应输出2,现输出1
prototype 多例,每次使用时都会创建一个实例
request web环境下,每一次独立请求存在唯一实例
session web环境下,每一次session存在有唯一实例
global session portlet的web应用的共享session中
websocket 每一次websocket连接中存在唯一实例
对象数量:全局唯一 存在多个
实例化时机:IoC容器启动时 getBean()或对象注入时
线程安全问题: 存在 不存在
执行效率:高 低
容器行为:Ioc容器准备初始化解析XML->为对象注入属性->IoC容器初始化完毕->IoC容器准备销毁
对象行为:对象实例化执行构造方法->调用init-method初始化方法->执行业务逻辑->调用destroy-method释放资源
Order实体类
package pers.thc.spring.IoC.lifecycle;
public class Order {
private Float price;
private Integer quantity;
private Float total;
public Order(){
System.out.println("创建Order对象,"+this);
}
public void init(){
System.out.println("执行init()方法");
total=price*quantity;
}
public void destroy(){
System.out.println("释放与订单对象相关的资源");
}
public void pay(){
System.out.println("订单金额为:"+total);
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
System.out.println("设置price:"+price);
this.price = price;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
System.out.println("设置quantity:"+quantity);
this.quantity = quantity;
}
public Float getTotal() {
return total;
}
public void setTotal(Float total) {
this.total = total;
}
}
application Context.xml
Application类
package pers.thc.spring.IoC.lifecycle;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class LifeCycleApplication {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext-lifecycle.xml");
System.out.println("========IoC容器已初始化========");
Order order1 = context.getBean("order1", Order.class);
order1.pay();
context.registerShutdownHook();//调用destroy-method方法销毁bean实例
}
}
注解开发: 三类注解
组件装配注解-声明当前类的功能和职责 四类组件类型注解:
@Component 组件注解,通用注解,被注解描述的类将被IoC容器管理并实例化
@Controller 语义注解,MVC控制层
@Service 语义注解,MVC业务层
@Repository 语义注解,MVC数据持久化层 开启组件扫描:
自动装配注解-根据属性特征自动注入对象 两类自动装配注解:
按类型装配:
@Autowired 按容器内对象类型动态诸如属性,由Spring机构提供
@Inject 基于JSR-330(Denpendency Inject for java)标准,其他同@Autowired,但不支持required属性
按名称装配:
@Named 与@Inject配合使用,JSR-330标准,按属性名自动装配属性
@Resource 基于JSR-250规范,优先按名称、再按类型智能匹配
元数据注解-更细化的辅助IoC容器管理对象的注解
@Primary 按类型装配时出现多个相同类型对象,拥有此注解对象优先被注入
@PostConstruct 描述方法,相当于XML中init-method配置的注解版本
@PreDestroy 描述方法,相当于XML中destroy-method配置的注解版本
@Scope 设置对象的scope属性
@Value 为属性注入静态数据
@Configuration 描述类,说明当前类时Java Config配置类,完全替代XML文件
@Bean 描述方法,方法返回对象将被IoC容器管理,beanId默认为方法名
@importResource 描述类,加载静态文件,可以使用@Value注解获取
@ComponentScan 描述类,同XML的context:component-scan标签
Maven工程依赖spring-test
利用@RunWith(让Spring接管JUnit4的控制权)与@ContextConfiguration(初始化过程中加载哪个初始化文件)描述测试用例类
测试用例类从容器获取对象完成测试用例的执行
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import pers.thc.spring.IoC.springtest.service.UserService;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext-test.xml"})
public class SpringTestor {
@Resource
private UserService userService;
@Test
public void testUserService(){
userService.createUser();
}
}



