在这里插入图片描述
https://start.spring.io

一、Spring入门
1、Spring全家桶(大致分为四个方面)
Spring Framework: Spring 框架,是基石、是核心。
Spring Boot:利用SpringBoot构建项目,在这个项目基础上做Spring开发更容易,更方便。
Spring Cloud:做微服务的。当项目很大时,很难维护,我们可以用Spring Cloud分成若干个子项目,然后把他们集成在一起,但开发难度有所提高。
Spring Cloud Data Flow:Spring做数据集成的一个功能。当应用中有很多客户端,那么这些客户端所采集到数据心形态各异,通过Spring Cloud Data Flow将数据集成在一起,形成更有价值的数据。
本项目没有用到所有这四个,会用前两种。

Spring官网:
https://spring.io

在这里插入图片描述

二、Spring Framework Spring框架(分为四部分)
第一部分:Spring Core
包括IOC、AOP。IOC,AOP都是用来管理对象的一种思想。我们通常由Spring管理的对象叫做Bean,那么IOC、AOP管理的是Bean对象。IOC是一种面向对象的编程思想,AOP是一种面向切面的编程思想。总之,通过IOC和AOP可以管理一切Bean对象,比如第三方框架也可以拿来整合。
第二部分:Spring Data Access
Spring Data Access是Spring访问数据库的功能。我们会用到Transactions来管理事务、SpringMyBatis整合Mybits。
第三部分:Web Servlet
在Web开发是会用到Spring MVC。
第四部分:Integration(集成)
我们会在Integration(集成)中用Spring发邮件(Email)、定时任务(Scheduling)、消息队列(AMQP)、安全控制(Security)。
在Spring还有很多可以在官方手册中看到:https://spring.io/projects/spring-framework

需要先学好IOC,其他的功能才能容易学会
在这里插入图片描述
三、Spring IOC
1、IOC是一种缩写,全称为 Inversion of Control -控制反转、是一种面向对象编程的设计思想。
2、IOC通过Dependency Injection-依赖注入,是一种方式,是IOC思想的实现方式,通过依赖注入实现对bean对象管理是降低耦合度,便于维护。
3、Dependency Injection依赖注入的实现又基于IOC Container-IOC容器,是实现依赖注入的关键,本质上是一个工厂。
在这里插入图片描述

在这里插入图片描述
这张图演示的IOC大概的原理,来源于官网手册,其中The Spring Container就是IOC容器,容器帮我们管理Bean的前提是具有两个条件,一是Bean的类型(Your Business Object(POJOS)),二是配置文件(Configuration Metadata)
补充解释:
在这里插入图片描述

package com.Ring.community;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CommunityApplication {

	public static void main(String[] args) {
		SpringApplication.run(CommunityApplication.class, args);
	}

}

SpringApplication.run(CommunityApplication.class, args); :Spring应用运行了,启动了Tomcat并且帮我们自动创建了Spring IOC容器。Spring容器创建后会自动的扫描Bean,将Bean装配到容器中。那些Bean会装配到容器。CommunityApplication.class类相当于配置文件,@SpringBootApplication 这是一个注解,这个注解标识了这个类,下图为@SpringBootApplication的底层。

在这里插入图片描述

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM,
				classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * @return the classes to exclude
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	/**
	 * Exclude specific auto-configuration class names such that they will never be

@SpringBootApplication 是由其他注解所组成的,
@SpringBootConfiguration表示这类是配置文件,
@EnableAutoConfiguration表示启动这个自动配置,
@ComponentScan表示逐渐扫描,能够自动扫描某些包下的Bean,实现自动装配Bean,它不是扫描全部的Bean,它会扫描配置类所在包以其子包下的Bean并且所在Bean上要有@Controller注解。在这里插入图片描述
与@Controller注解等价的是@Service注解,@Service注解中有@Componment注解,在Bean上加上@Componment注解也可实现的。
在这里插入图片描述

* @see Repository
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}

还有一个是@Repository注解,在@Repository注解中也有@Component注解。
在这里插入图片描述

 * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

}

他们区别在于如果使用的是业务组件就用@Service注解,如果开发是一个出来请求的组件,就用@Controller注解,如果开发的是一个数据库访问的组件就用@Repository,通用的就是@Component。

IOC容器的演示(在测试类test中进行):
在这里插入图片描述
我们在测试类中也希望用用到CommunityApplication这个配置类,则通过在测试类中添加@ContextConfiguration(classes=CommunityApplication.class)
在这里插入图片描述

那个类想实现Spring容器,则实现一个接口implements ApplicationContextAware并显示该接口的方法setApplicationContext。

在这里插入图片描述
在实现方法setApplicationContext中传入了一个参数ApplicationContext,这个参数就是一个spring容器,它是一个接口,ApplicationContext继承于HierarchicalBeanFactory,HierarchicalBeanFactory继承于BeanFactory,BeanFactory就是Spring容器的顶层结构。ApplicationContext的功能更强一点,所以我们用ApplicationContext
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后我们添加了一个成员变量applicationContext,记录这个容器。
在这里插入图片描述
添加this.applicationContext=applicationContext;
在这里插入图片描述
编写一个测试方法,使用Spring容器
在这里插入图片描述
在这里插入图片描述

package com.Ring.community;




import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;


@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes=CommunityApplication.class)
public class CommunityApplicationTests implements ApplicationContextAware {

	private ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext=applicationContext;

	}

	@Test
	public void testApplication(){
		System.out.println(applicationContext);
	}
}

建一个包,专门访问数据库,包名为dao,在包中建立一个接口,接口中定义一些方法。
在这里插入图片描述
在这里插入图片描述

package com.Ring.community.dao;

public interface AlphaDao {
    String select();
}

接口不能直接用,需要有一个接口的实现类。
在这里插入图片描述

package com.Ring.community.dao;

import org.springframework.stereotype.Repository;

@Repository("alphaHibernate")//自定义名为alphaHibernate,默认为类名小写,可以强制通过类名查找
public class AlphaDaoHibernateImpl implements AlphaDao {
    @Override
    public String select() {
        return "Hibernate";
    }


}


从容器中获取自动装配的Bean,getBean()方法是获取Bean,可以通过名字获取也可以通过类型获取,一般是通过类型或去,获取Bean后调用Bean中的select方法。结果我们成功的获取到了Bean并获得方法执行的 结果。


	package com.Ring.community;


import com.Ring.community.dao.AlphaDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;


@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes=CommunityApplication.class)
public class CommunityApplicationTests implements ApplicationContextAware {
	private ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
		this.applicationContext=applicationContext;
	}
	@Test
	public void testApplicationContext(){
		System.out.println(applicationContext);

		AlphaDao alphaDao=applicationContext.getBean(AlphaDao.class);
		System.out.println(alphaDao.select());
	}

	}



这么做的好处的体现,我们再写一个Bean,体会它的优势。假设我们想将Hibenate替换为MyBatis,这个项目中我们可以这么做,在以上基础上我们在建立一个实现类AlphaDaoMyBatisImpl,我们只需要在需要的上面加上一个注解@Primary就可以。
请添加图片描述

package com.Ring.community.dao;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;

@Repository
@Primary//具有更高的优先级
public class AlphaDaoMyBatisImpl implements AlphaDao {
    @Override
    public String select() {
        return "MyBatis";
    }
}

可能会遇到这样一个问题,比如说我们想要还是需要Hibernate实现类,那如何得到呢?我们可以通过Bean的别名实现,首字母小写。
请添加图片描述
然后我们在CommunityApplicationtests中重新的获取Bean。
请添加图片描述

package com.Ring.community;


import com.Ring.community.dao.AlphaDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;


@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes=CommunityApplication.class)
public class CommunityApplicationTests implements ApplicationContextAware {
	private ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
		this.applicationContext=applicationContext;
	}
	@Test
	public void testApplicationContext(){
		System.out.println(applicationContext);

		AlphaDao alphaDao=applicationContext.getBean(AlphaDao.class);
		System.out.println(alphaDao.select());

		alphaDao=applicationContext.getBean("alphaHibernate",AlphaDao.class);
		System.out.println(alphaDao.select());//测试通过名字查找执行对应类
	}
	
	}




我们在新建一个Bean,我们需要业务组件会创建一个service包,然后我们新建一个AlphaService的类,添加@Service注解。然后添加init()方法,在该方法上加@PostConstruct注解,@POSTConstruct注解的意思这个方法会在构造器之后,为了便于观察我们可以加一个构造器AlphaService。然后添加一个destroy方法,在该方法中添加一个@PreDestroy注解,@PreDestroy注解是在销毁之前调用。
请添加图片描述

package com.Ring.community.service;

import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Service
//@Scope("prototype")
public class AlphaService {

    public AlphaService(){
        System.out.println("实例化AlphaService");
    }
    @PostConstruct
    public void init(){
        System.out.println("初始化AlphaService");
    }
    @PreDestroy
    public void destory(){
        System.out.println("销毁AlphaService");
    }

}

写完以后测试一下,看看可不可以自动调用和销毁。Bean只能实例化一次,只销毁一次。然后我们在实例化一次会发现在程序的启动过程中只启动了一次,说明被Spring容器管理的Bean是单例的。请添加图片描述

如果我们不想是单例的,可以是通过添加@Scope注解在AlphaService中,该注解默认是singlton单例,如果多个实例就是prototype,每次访问都会有一个实例,记得要注释掉。请添加图片描述
有时候我们希望在容器中装配第三方Bean,我们只需要写一个配置类,然后在配置类中通过Bean声明来解决这个问题。新建一个Config包,然后建一个配置类实例AlphaConfig,并配置一个@Configration, 表示这个类是 一个配置类。然后定义第三方Bean,需要在方法中添加@Bean注解。请添加图片描述

package com.Ring.community.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.text.SimpleDateFormat;

@Configuration
public class AlphaConfig {
    @Bean
    public SimpleDateFormat SimpleDateFormat(){
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }
}

然后,我们再回到测试类中在编写一个测试方法。
请添加图片描述

    @Test
	public void testBeanConfig(){
		SimpleDateFormat simpleDateFormat=
				applicationContext.getBean(SimpleDateFormat.class);
		System.out.println(simpleDateFormat.format(new Date()));
	}

什么是依赖注入?注入的注解@Autowired加在一个成员变量上,意思是我希望spring容器注入到这个属性。同理获取AlphaService和SimpleDateFormat也是同样。请添加图片描述

    @Autowired
	private AlphaDao alphaDao;

	@Autowired
	private AlphaService alphaService;

	@Autowired
	private SimpleDateFormat simpleDateFormat;

	@Test
	public void testDI(){
		System.out.println(alphaDao);
		System.out.println(alphaService);
		System.out.println(simpleDateFormat);
	}

我们在项目中实际开发如何使用这个思想,在开发中由Controller处理开发过程中的请求,会调用Service业务组件中的业务,然后业务组件会调用Dao,他们彼此之间相互依赖,因此它们可以通过依赖注入的方式来实现。
请添加图片描述

请添加图片描述
请添加图片描述

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐