Spring的回顾
首先我们回顾下Spring的IOC/DI/AOP等核心
回顾Spring:
IOC(控制反转):
主要描述创建对象的过程—实例化
比如需要使用某个对象时,原来的做法是直接new出来, 而有了Spring之后则是从Spring容器中(Map集合)直接获取出来即可。创建对象的权利交给了Spring框架。Spring框架默认采用单例模式帮我们创建对象,以bean标签的id为键(如果没有id属性则默认使用类名称) ,以创建出来的对象为值,保存到Spring容器中(Map集合)
DI(依赖注入):
主要描述创建对象之后给对象的属性赋值的过程–这就是 初始化
原先一个对象拥有另一个对象的写法是private lUserDao userDao = new UserDaolmpl0;这种写法属于关联关系,为了降低耦合度,将关联关系改造成依赖关系(就是将对象通过属性的set方法或者构造方法传入进行赋值),Spring在对所有对象的属性进行初始化的时候会自动到Spring容器中查找合适的对象进行注入。
AOP(面向切面编程):
在程序运行过程中,不改变原先代码的情况下,在用户不知不觉中插入其他业务逻辑。主要用来做事务管理/日志管理。SpringAOP其实就是代理模式的一个经典案例。
XML方式配置IOC
1、创建一个项目(Maven结构或其他结构都可以)
2、导包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
3、创建XML配置文件
4、创建一个MyBean的类
public class MyBean {
}
5、编写配置文件XML
<bean id="myBean" class="cn.itsource._01_xml_config.MyBean"/>
6、测试
public class XMLConfigTest {
@Test
public void testMyBean(){
//加载配置文件,获取Spring容器
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
//通过Spring容器获取到Bean对象
MyBean bean = applicationContext.getBean(MyBean.class);
//打印Bean对象
System.err.println(bean);
}
}
上面的都是之前配置的方式,接下来我们看看Spring注解配置
Spring注解配置
一、Anno配置IOC
1、创建配置类
@Configuration:Spring的配置标签,打了这个标签的类可以被识别为Spring的配置类 , 相当于是 spring.xml
@Bean :Spring的Bean定义标签,打了个标签的方法所有返回的对象就可以自动的被Spring进行管理//相当于是class=“cn.itsource._01_xml_config.MyBean” />
@Configuration
public class SpringConfig {
//定义 MyBean
@Bean
public MyBean myBean(){
MyBean myBean = new MyBean();
return myBean;
}
}
2、创建MyBean的类
public class MyBean {
}
3、测试
public class JavaConfigTest {
@Test
public void testMyBean(){
AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
MyBean bean = configApplicationContext.getBean(MyBean.class);
System.err.println(bean);
}
}
二、注解@ComponentScan
@ComponentScan : 开启Spring,IOC组件的自动扫描 ,相当于是XML配置中的 <context:component-scan base-package=*>
@ComponentScan 默认可以扫描当前包,及其子包
1、直接在MyBean类的上面打上注解Component
@Component
public class MyBean {
}
2、创建配置类
//主配置类
@Configuration
//开启Spring,IOC组件的自动扫描 ,相当于是XML配置中的 <context:component-scan base-package=*>,默认可以扫描当前包,及其子包
@ComponentScan(value="cn.itsource._03_component_scan")
public class SpringConfig {
}
3、测试
public class JavaConfigTest {
@Test
public void testMyBean(){
//1.加载配置文件,获取到容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
//2.通过容器获取Bean
MyBean myBean = applicationContext.getBean(MyBean.class);
//3.打印Bean
System.out.println(myBean);
}
}
三、依赖注入DI
注入对象的方式:
1、调用方法
2、传入参数
3、使用@Autowired注入
我们通过一个需要来实现上面三个方式:
需求:
定义MyBean ,
从容器中拿到的 MyBean中 , 需要有 OtherBean
从容器中可以直接获取到OtherBean
从容器中拿到的OtherBean要求和MyBean中拿到的OtherBean 是同一个
实现步骤:
1、创建MyBean的类
public class MyBean {
private String name;
//将OtherBean传入到MyBean中,并且搞一个Set方法
private OtherBean otherBean ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public OtherBean getOtherBean() {
return otherBean;
}
public void setOtherBean(OtherBean otherBean) {
this.otherBean = otherBean;
}
}
2、创建OtherBean的类
public class OtherBean {
}
3、配置类
@Configuration
public class SpringConfig {
@Bean
public OtherBean otherBean(){
OtherBean otherBean = new OtherBean();
return otherBean;
}
@Bean
public MyBean myBean(OtherBean otherBean){
MyBean myBean = new MyBean();
//这里方式只能通过MyBean获取OtherBean, 不能通过容器拿到OtherBean
//myBean.setOtherBean( new OtherBean() );
//第一种方式: 调用方法
//myBean.setOtherBean( otherBean() );
//第二种方式 :传参数
myBean.setOtherBean(otherBean);
return myBean;
}
}
4、测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class JavaConfigTest {
@Autowired
private ApplicationContext applicationContext;
//这是第三种方式:使用注解的方式注入
@Autowired
private MyBean myBean;
@Test
public void testMyBean(){
//2.通过容器获取Bean
MyBean myBean = applicationContext.getBean(MyBean.class);
System.out.println(myBean);
System.out.println(myBean.getOtherBean());
OtherBean otherBean = applicationContext.getBean(OtherBean.class);
System.out.println(otherBean);
}
}
四、条件注解@Conditional
注解@Conditional打在Bean的定义方法上来进行条件判断,如果不满足条件就不会定义Bean,并且Condition是一个条件接口,所以我们一般都要进行覆写
那么就来操作一下:判断一个系统是否是Windows系统
1、依然创建一个MyBean类
public class MyBean {
}
2、配置类进行配置
@Configuration
@Conditional(value = WindowBeanCondition.class)
public class SpringConfig {
/**
* @Conditional :条件标签,打方Bean的定义方法上,指定这个bean需要满足条件才能定义
* Condition 接口是条件的接口 ,
*/
@Conditional(value = WindowBeanCondition.class)
@Bean
public MyBean myBean(){
return new MyBean();
}
}
3、创建WindowBeanCondition类实现Condition接口进行方法覆写
//条件类 ,判断系统是window就满足条件
public class WindowBeanCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//判断系统是否window
String osName = context.getEnvironment().getProperty("os.name");
System.out.println(osName);
if(osName.equals("linux")){
return true;
}
return false;
}
}
4、测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)//加载配置类
public class JavaConfigTest {
@Autowired
private ApplicationContext applicationContext;
@Test
public void testMyBean(){
//2.通过容器获取Bean
MyBean myBean = applicationContext.getBean(MyBean.class);
System.out.println(myBean);
}
}
五、@Import注解
@Import用来导入@Configuration注解的配置类、声明@Bean注解的bean方法、导入ImportSelector的实现类或导入ImportBeanDefinitionRegistrar的实现类>
1、在配置类中直接导入Bean
@Configuration
@Import({OtherConfig.class,TempBean.class})
public class SpringConfig {
}
2、导入配置类
我们需要实现ImportSelector
```java
//导入选择器
public class MyImportSelector implements ImportSelector {
//方法返回的类 , 会交给Spring容器管理
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"cn.itsource._08_import_selector.MyBean","cn.itsource._08_import_selector.OtherBean"};
}
}
其次我们直接在配置类中进行导入
@Configuration
@Import(value = MyImportSelector.class )
public class SpringConfig {
}
3、导入注册器
实现ImportBeanDefinitionRegistrar接口
//bean注册器
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
// BeanDefinitionRegistry :用来注册bean的注册器
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册Mybean
RootBeanDefinition myBeanDefinition = new RootBeanDefinition(MyBean.class);
RootBeanDefinition otherBeanDefinition = new RootBeanDefinition(OtherBean.class);
registry.registerBeanDefinition("myBean",myBeanDefinition);
registry.registerBeanDefinition("otherBean",otherBeanDefinition);
}
}
在配置类中导入
//导入注册器
@Configuration
@Import(value = MyImportBeanDefinitionRegistrar.class)
public class SpringConfig {
}