什么是spring?
简单来说 ,spring就是一个轻量级的java开发框架,用来开发企业级应用,让开发者专注于业务,而不是底层的框架。
为什么要用spring?
spring的核心概念有两个IOC和AOP。IOC(Inversion of Control)也就是常说的控制反转,它和我们平时编程有啥不一样呢?我们平时编程都是使用new来实例化类或者其他的一些方法。这样有一个坏处,那就是你的应用程序和你使用的类紧紧耦合在了一起,复用起来很不方便。因为要使用你的程序必须要有你实例化的类,而且一旦你使用的类发生了改变,你的整个程序都需要改变。IOC就是为了解决这个问题,使用@Autowired注解像这样:
@Autowired SomeObject object;
你就可以使用这个类的实例了,这里的SomeObject一般是一个接口,这样你的应用程序就和实际的类解耦合了,当类发生改变时应用程序不需要做任何改变。那么重点来了spring怎么实现控制反转这一编程思想的?
spring容器的实现
spring中IOC的实现是通过BeanFactory这一接口,这个接口代表了一个IOC容器,IOC容器包含了你配置的需要使用的类的实例,你可以使用@Autowired注解或者直接通过getBean方法获取你配置的类的实例。接口的详细代码如下:
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
在spring中还有一个概念叫做应用上下文,抽象出来的接口是ApplicationContext,应用上下文其实也是一个容器,但是它比容器具有更多的功能,spring真正使用的是应用上下文。BeanFactory相当于一个基础设施。
AOP简单介绍
AOP 面向切面编程,什么意思?你就想一个问题,有一个功能在应用程序的每个地方都需要用到,帮这个功能抽象出来而不是散落在程序的各个角落。这和一个切面是不是很像,这个其他方法调用时都需要从这个切面通过。具体实现呢我不知道

spring的使用
spring在Java Web程序中的启动
web.xml中配置启动
<web-app>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<!--这个是父上下文的配置文件位置-->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
编程式启动
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletCxt) {
// Load Spring web application configuration
AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
//AppConfig是上下文的配置类
ac.register(AppConfig.class);
ac.refresh();
// Create and register the DispatcherServlet
DispatcherServlet servlet = new DispatcherServlet(ac);
ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
registration.setLoadOnStartup(1);
//spring mvc 映射设置
registration.addMapping("/app/*");
}
}
为什么tomcat容器会加载WebApplicationInitializer类来注册上下文和DispatcherServlet?原因是由于spring实现了ServletContainerInitializer(这个是servlet技术中的接口)这个接口,并把WebApplicationInitializer声明为了需要处理的类型源码如下://处理类型的声明
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException {
List<WebApplicationInitializer> initializers = new LinkedList<>();
if (webAppInitializerClasses != null) {
for (Class<?> waiClass : webAppInitializerClasses) {
// Be defensive: Some servlet containers provide us with invalid classes,
// no matter what @HandlesTypes says...
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
try {
initializers.add((WebApplicationInitializer)
ReflectionUtils.accessibleConstructor(waiClass).newInstance());
}
catch (Throwable ex) {
throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
}
}
}
}
if (initializers.isEmpty()) {
servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
return;
}
servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
AnnotationAwareOrderComparator.sort(initializers);
for (WebApplicationInitializer initializer : initializers) { //调用对应的方法初始化上下文
initializer.onStartup(servletContext);
}
}
}
在springMVC中一般有两个应用上下文,一个是ContextLoaderListner加载的上下文,还有一个时DispatcherServlet加载的上下文。者两个上下文是父子关系。父上下文中的bean可以继承到子上下文中。
来源:https://www.cnblogs.com/zshjava/p/11325501.html