三种方式:
- 隐式的bean发现机制和自动装配(常用)
- 在java中进行显示的配置
- 在xml中进行显示的配置
创建项目
实现音响系统,CdPlayer,CompactDisc
package soundsystem;
import org.springframework.stereotype.Component;
@Component
public class CompactDisc {
public CompactDisc() {
super();
System.out.println("CompactDisc无参构造参数");
}
public void play(){
System.out.println("正在播放音乐....");
}
} package soundsystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CdPlayer {
private CompactDisc cd;
public CdPlayer() {
super();
System.out.println("Cdplayer无参构造函数");
}
@Autowired
public CdPlayer(CompactDisc cd) {
this.cd = cd;
System.out.println("CdPlayer的有参构造函数");
}
public void play(){
cd.play();
}
} package soundsystem;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class App {
public static void main(String[] args)
{
ApplicationContext context = new AnnotationConfigApplicationContext(App.class);
CdPlayer player = context.getBean(CdPlayer.class);
player.play();
}
} 使用配置类
把主类与@ComponentScan进行解耦
@Configuration:当前的类是一个配置类 新建AppConfig(配置类)
package soundsystem;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//配置类
@Configuration
@ComponentScan
public class AppConfig {
} 原来的主类: package soundsystem;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App {
public static void main(String[] args)
{
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
CdPlayer player = context.getBean(CdPlayer.class);
player.play();
}
} 使用junit单元测试
加入junit的jar包
group 'com.yuan.wiringAuto'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
jcenter()
}
dependencies {
// https://mvnrepository.com/artifact/org.springframework/spring-context
compile group: 'org.springframework', name: 'spring-context', version: '4.3.13.RELEASE'
testCompile group: 'junit', name: 'junit', version: '4.12'
// https://mvnrepository.com/artifact/log4j/log4j
compile group: 'log4j', name: 'log4j', version: '1.2.17'
// https://mvnrepository.com/artifact/junit/junit
testCompile group: 'junit', name: 'junit', version: '4.12'
} 单元测试的包必须跟main/java下的包一致 AppTest:
package soundsystem;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AppTest {
@Test
public void testPlay(){
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
CdPlayer player = context.getBean(CdPlayer.class);
player.play();
}
} spring自带的test模块
引入jar包:
// https://mvnrepository.com/artifact/org.springframework/spring-test testCompile group: 'org.springframework', name: 'spring-test', version: '4.3.13.RELEASE'
package soundsystem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//RunWith(SpringJUnit4ClassRunner.class):自动初始化spring上下文环境
@RunWith(SpringJUnit4ClassRunner.class)
//自动读取配置文件
@ContextConfiguration(classes = AppConfig.class)
public class AppTest {
@Autowired
private CdPlayer player;
@Test
public void testPlay(){
player.play();
}
}
使用接口开发
1. @Component写在实现类上
2. 再调用时声明接口类型的成员变量
UserService:
package com.yuan.demo.service;
public interface UserService {
void add();
} UserServiceNormal: package com.yuan.demo.service.impl;
import com.yuan.demo.service.UserService;
import org.springframework.stereotype.Component;
@Component
public class UserServiceNormal implements UserService {
@Override
public void add() {
System.out.println("添加用户");
}
} AppConfig: package com.yuan.demo.service;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class AppConfig {
} test:
package com.yuan.demo.service;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testAdd(){
userService.add();
}
} 自动装配的歧义性
有两个实现类的时候,autowired userservice的时候不知道注入哪一个
package com.yuan.demo.service.impl;
import com.yuan.demo.service.UserService;
import org.springframework.stereotype.Component;
@Component
public class UserServiceNormal implements UserService {
@Override
public void add() {
System.out.println("添加用户");
}
} package com.yuan.demo.service.impl;
import com.yuan.demo.service.UserService;
import org.springframework.stereotype.Component;
@Component
public class UserServiceFestival implements UserService {
@Override
public void add() {
System.out.println("注册用户并发送优惠券");
}
}
解决办法
(1)直接声明具体的Userservice
package com.yuan.demo.service;
import com.yuan.demo.service.impl.UserServiceNormal;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired
private UserServiceNormal userService;
@Test
public void testAdd(){
userService.add();
}
}
(2)使用首选bean @Primary package com.yuan.demo.service.impl;
import com.yuan.demo.service.UserService;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class UserServiceFestival implements UserService {
@Override
public void add() {
System.out.println("注册用户并发送优惠券");
}
} import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testAdd(){
userService.add();
}
} (3)使用限定符
类定义的时候不需要明确使用用哪个,测试的时候指定就可以了
package com.yuan.demo.service.impl;
import com.yuan.demo.service.UserService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
@Qualifier("normal")
public class UserServiceNormal implements UserService {
@Override
public void add() {
System.out.println("添加用户");
}
} package com.yuan.demo.service.impl;
import com.yuan.demo.service.UserService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Qualifier("festival")
public class UserServiceFestival implements UserService {
@Override
public void add() {
System.out.println("注册用户并发送优惠券");
}
} package com.yuan.demo.service;
import com.yuan.demo.service.impl.UserServiceNormal;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired
@Qualifier("normal")
private UserService userService;
@Test
public void testAdd(){
userService.add();
}
} 在声明的时候指定bean的id(@Component("normal"),默认id是首字母小写的类名),在装配的时候使用@Qualifier
package com.yuan.demo.service.impl;
import com.yuan.demo.service.UserService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component("normal")
public class UserServiceNormal implements UserService {
@Override
public void add() {
System.out.println("添加用户");
}
} package com.yuan.demo.service.impl;
import com.yuan.demo.service.UserService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component("festival")
public class UserServiceFestival implements UserService {
@Override
public void add() {
System.out.println("注册用户并发送优惠券");
}
} package com.yuan.demo.service;
import com.yuan.demo.service.impl.UserServiceNormal;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired
@Qualifier("festival")
private UserService userService;
@Test
public void testAdd(){
userService.add();
}
} (5)java标准解决方法 在test的时候使用@Resource(name="festival"),可以替代 @Autowired + @Qualifier("festival")
package com.yuan.demo.service;
import com.yuan.demo.service.impl.UserServiceNormal;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Resource(name="festival")
private UserService userService;
@Test
public void testAdd(){
userService.add();
}
} 处理分层架构
浏览器——》web层(controller)——》业务层(service)——》数据访问层(dao)——》数据库
三层架构模型,逐层编写代码
通过xml启动组件扫描
在resources包下新建 applicationContext.xml, App.config配置类可以删除:
<?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:component-scan base-package="com.yuan.demo" /> </beans>
test:
package com.yuan.demo.controller;
import com.yuan.demo.AppConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserControllerTest {
@Autowired
private UserController userController;
@Test
public void testAdd(){
userController.add();
}
}

京公网安备 11010502036488号