Spring 5 基础

Spring 5 基础


(一)Bean作用域

Bean作用域适用范围
sigleton在默认IoC容器BeanFactory中就能用
prototype在默认IoC容器BeanFactory中就能用
request只有在ApplicationContext容器中才可用
session只有在ApplicationContext容器中才可用
application只有在ApplicationContext容器中才可用
websocket只有在ApplicationContext容器中才可用
自定义Scope:thread……

参考Spring
Spring 5去除了global-session,新增了applicationwebsocket两种Bean作用域

1.singleton

  • 默认Bean作用域,在默认IoC容器BeanFactory中就能用。
  • 单个IoC容器中只有一个Bean实例,每次请求返回的都是同一个。

使用

  1. 注解:
1
2
3
@Component  //冗余,默认singleton
@Scope("sigleton") //冗余,默认就是singleton
public class BeanClass{}
  1. XML:
1
2
3
<bean id="beanId" class="com.bat.BeanClass" scope="singleton" />
<!-- 或者:直接不写scope属性,默认就是singleton -->
<bean id="beanId" class="com.bat.BeanClass" />

Spring Bean的单例模式采用的是双重判断加锁的懒汉模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//@param: String beanName   get Bean by name
//@param: boolean allowEarlyReference 是否允许提前指向
// true为立即加载,false为延迟加载
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if(singletonObject == null && isSingletonCurrentlyInCreation(beanName)){
synchronized(this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
//双重判断加锁的单例模式:
//首先从缓存中获取bean,如果不存在则加锁,
//再从缓存中获取一次bean,如果不存在则创建。
//【这样双重判断,可以避免在加锁的瞬间bean被创建,导致重复】
if(singletonObject == null && allowEarlyReference){
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if(singletonFactory != null) {
singletonObject = singletonFacotry.getObject();
this.earlySinletonObjects.put(beanName, sinletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletionObject != NULL_OBJECT ? singletonObject : null);
}

2.prototype

  • 在默认IoC容器BeanFactory中就能用。
  • 每次请求就返回一个新的Bean实例。

    原型模式:Bean实例只存在一个,但是每次请求就克隆一份返回。

使用

  1. 注解:
1
2
3
@Component
@Scope("prototype")
public class BeanClass{}
  1. XML:
1
<bean id="beanId" class="com.bat.BeanClass" scope="prototype" />

3.request

  • ApplicationContext容器中才能用。
  • 每一个HTTP请求(request)中创建一个Bean实例,一个请求中的Bean属性变化不影响另一个请求中的Bean。

使用

  1. 注解:
1
2
3
@Component
@Scope("request") //或者:@RequestScope
public class BeanClass{}
  1. XML:
1
<bean id="beanId" class="com.bat.BeanClass" scope="request" />

4.session

使用

  1. 注解:
1
2
3
@Component
@Scope("session") //或者:@SessionScope
public class BeanClass{}
  1. XML:
1
<bean id="beanId" class="com.bat.BeanClass" scope="session" />

5.application

  • ApplicationContext容器中才能用。
  • 每一个ServletContext中创建一个Bean实例。

使用

  1. 注解:
1
2
3
@Component
@Scope("application") //或者:@ApplicationScope
public class BeanClass{}
  1. XML:
1
<bean id="beanId" class="com.bat.BeanClass" scope="application" />

6.websocket

使用

  1. 注解:
1
2
3
@Component
@Scope("websocket")
public class BeanClass{}
  1. XML:
1
<bean id="beanId" class="com.bat.BeanClass" scope="websocket" />

7.自定义作用域:thread

通过CustomScopeConfigurer,将SimpleThreadScope注册到容器内:

1
2
3
4
5
6
7
8
9
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>

使用

  1. 注解:
1
2
3
@Component
@Scope("thread")
public class BeanClass{}
  1. XML:
1
<bean id="beanId" class="com.bat.BeanClass" scope="thread" />

(二)Bean配置

1.通过XML配置

1
<bean id="beanId" class="com.bat.BeanClass" />

2.通过注解配置

(1)component注解

  1. @Component标注在Java类上,@ComponentScan调用链可以扫描到该类,并注入到IoC容器中;
  2. @Repository将DAO层类注入IoC容器,还能使得DAO抛出的未受检查异常有资格转换为DataAccessException
  3. @Service将Service层类注入IoC容器;
1
2
@Sevice
public class EmployeeManagerImpl implements EmployeeManager{...}
  1. @Controller将Controller层类注入IoC容器,使得该类中可以用@RequestMapping注解;
  2. @ComponentScan
1
2
3
@Configuration
@ComponentScan(basePackages = "com.bat.service")
public class AppConfig {}

(2)bean注解

  1. @Bean
  2. @Configuration
1
2
3
4
5
6
7
8
9
@Configuration
public class AppConfig {

@Bean
public EmployeeManager employeeManager() {
return new EmployeeManagerImpl();
}

}

(三)Bean延迟加载

  • 首先明确一点,只有作用域为singleton的Bean才能延迟加载!!!
  • ApplicationContext实现的默认行为是在启动服务器时,将所有singleton的Bean提前进行实例化(即依赖注入,DI),通常情况这是一件好事,因为这样在配置中的任何错误就会被立即发现,否则的话可能需要几个小时甚至几天
  • 如果这种默认行为不是你想要的,那么你可以将某个Bean设置为延迟加载,延迟加载的Bean不会在ApplicationContext启动时提前被实例化,而是第一次向容器请求Bean时才被初始化

1.XML方式 延迟加载

  1. 单个Bean延迟加载:<bean lazy-init = "true" />
1
2
3
4
5
6
<beans>

<bean id="employeeManager" class="com.bat.BeanClass"
lazy-init="true"/>

<beans>
  1. 全局Bean延迟加载:<beans default-lazy-init="true">
1
2
3
4
5
<beans default-lazy-init="true">

<bean id="employeeManager" class="com.bat.BeanClass" />

</beans>

2.注解方式:@Lazy

  1. 单个Bean延迟加载:@Lazy加在方法上
1
2
3
4
5
6
7
8
@Configuration
public class AppConfig{
@Bean
@Lazy
public EmployeeManager employeeManager() {
return new EmployeeManagerImpl();
}
}
  1. 全局Bean延迟加载:@Lazy加在配置类上
1
2
3
4
5
6
7
8
@Configuration
@Lazy
public class AppConfig{
@Bean
public EmployeeManager employeeManager() {
return new EmployeeManagerImpl();
}
}

(四)DispatcherServlet

什么是DispatcherServlet

  • DispatcherServletSpring网络应用的前端控制器(Controller),提供了一种请求处理机制,实际工作由可配置的委托组件执行
  • DispathcerServlet继承自javax.servlet.http.HttpServlet,通常由web.xml配置。
  • 网络应用可以定义任意多个DispatcherServlet实例,每一个Servlet单独加载自己的ApplicationContext。绝大多数情况下网络应用中都只有一个DispatcherServlet,所有访问该领域的请求都会被这个DispatcherServlet处理。
  • DispatcherServlet通过Spring配置类来发现请求分发、视图解析、异常处理的相关组件。

DispatcherServlet怎么使用WebApplicationContext

  • Spring应用中,对象被称为Bean,存活在一个容器中。容器负责创建Bean、管理Bean之间的依赖、管理整个Bean的生命周期,这个容器就被称为应用上下文(application context),通过ApplicationContext类创建。
  • WebApplicationContext是普通ApplicationContext的扩展,具有Servlet上下文信息ServletContextDispatcherServlet加载时,会查找WebApplicationContext的配置文件并进行加载
  • 实现ServletContextAware接口的Bean可以进入ServletContxt内部并进行操作。

DispatcherServlet配置

1.XML配置

  1. web.xml:创建DispatcherServlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet-context.xml</param-value>
</context-param>

<servlet>
<servlet-name>dispatcher-servlet</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>dispatcher-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
  1. applicationContext.xml:创建ApplicationContext,实现诸如请求分发、视图解析、异常处理等功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

</beans>

2.Java配置

  1. 实现WebAppInitializer接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ApplicationInitializer implements WebAppInitializer{
@Override
public void onStartup(ServletContext container) {
//创建root ApplicationContext
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class); //配置

//ServletContext监听ApplicationContext
container.addListener(new ContextLoadListener(rootContext));

//创建DipatcherServlet的ApplicationContext
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(DispatcherConfig.class); //配置

//配置DispatcherServlet
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
  1. 继承AbstractDispatcherServletInitializer抽象类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class ApplicationInitializer extends AbstractDispatcherServletInitializer {

@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}

@Override
protected WebApplicationContext createServletApplicationContext() {
XmlWebApplicationContext cxt = new XmlWebApplicationContext();
cxt.setConfigLocation("/WEB-INF/dispatcher-servlet-context.xml");
return cxt;
}

@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}

//Register filters
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new HiddenHttpMethodFilter(), new CharacterEncodingFilter() };
}
}
  1. 继承AbstractAnnotationConfigDispatcherServletInitializer抽象类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootConfig.class };
}

@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebMvcConfig.class };
}

@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}

DispatcherServlet相关Bean

  • HandlerMapping:将传入的网络URL请求映射到对应的处理器
  • HandlerAdaptor
  • HandlerExceptionResolver:允许编程处理异常,并将异常映射到视图
  • ViewResolver:解析对应URL需要返回的视图
  • LocaleResolver
  • LocaleContextResolver
  • ThemeResolver
  • MultipartResolver
  • FlashMapResolver
  • 可以通过继承对应类实现自定义Bean

(五)MVC注解

  • @Controller
  • @RequestMappingproduces属性和@ResponseBody/@RestController搭配使用,可以设置返回数据的类型(JSON/XML)以及编码(UTF-8)
1
2
3
4
5
//JSON格式,UTF-8编码
@RequestMapping(value="/xxx", produces={"application/json;charset=UTF-8"})

//XML格式,UTF-8编码
@RequestMapping(value="/xxx", produces={"application/xml;charset=UTF-8"})
  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

(六)跨域资源请求

  • @CrossOrigin

(七)Spring Security 5

  • @EnableWebSecurity注解
  • WebSecurityConfigurerAdaptor
  1. Maven依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
<spring.version>5.0.7.RELEASE</spring.version>
</properties>

<!-- Spring MVC Dependency -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- Spring Security Core -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- Spring Security Config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- Spring Security Web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.version}</version>
</dependency>
  1. @EnableWebSecurity配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
PasswordEncoder passwordEncoder;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.passwordEncoder(passwordEncoder)
.withUser("user").password(passwordEncoder.encode("123456")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder.encode("123456")).roles("USER", "ADMIN");
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/login").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/**").hasAnyRole("ADMIN", "USER")
.and().formLogin()
.and().logout().logoutSuccessUrl("/login").permitAll()
.and().csrf().disable();
}
}
-------------本文结束感谢您的阅读-------------

本文标题:Spring 5 基础

文章作者:DragonBaby308

发布时间:2019年09月04日 - 21:25

最后更新:2019年10月24日 - 22:40

原始链接:http://www.dragonbaby308.com/Spring5/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

急事可以使用右下角的DaoVoice,我绑定了微信会立即回复,否则还是推荐Valine留言喔( ఠൠఠ )ノ
0%