什么是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