初识Spring与SpringMVC

什么是Spring
Spring是一个轻量级的开源框架
Spring可以将各种框架整合在一起
Spring的核心是IOC和AOP

Spring框架的优点
将对象之间的依赖关系交给Spring,降低组件之间的耦合性
对主流的框架提供了很好的集成支持,如Hibernate,Struts2等
Spring DI机制降低了业务对象替换的复杂性
Spring的高度可开放性,并不强制依赖于Spring,开发者可自由选择

IOC/DI
IOC即控制反转,是一种设计思想
1.将主动创建对象变为被动接受
2.实现代码的解耦

DI即依赖注入,是IOC的一种实现
用容器来管理所i有对象

Spring容器

是Spring的核心,容器负责管理对象。

容器的两种实现:
BeanFactory :最简单容器,给DI提供基本支持
ApplicationContext:继承BeanFactory,有更多的功能实现

常用方法:
getBean方法:获取容器内指定对象
containBean方法:判断容器中是否存在指定的对象
isPrototype方法:判断指定的对象是否为非单例对象
isSingleton方法:判断指定的对象是否为单例对象

ApplicationContext的主要实现类

ClassPathXmlApplication:从类的根路径下加载xml配置文件
AnnotionConfigApplication:使用注解配置容器对象时,用次类创建spring容器

Xml装配Bean

使用bean标签来装配Bean对象

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(“application.xml”);
通过名字来获取Bean对象
User user = (User)ctx.getBean(“user”);
通过类型来获取Bean对象
User user1 = ctx.getBean(User.class)

默认情况下,Spring只为每个在IOC容器里声明的Bean创建一个唯一实例,整个IOC容器都能共享此实例,即单例模式

依赖注入

Bean对象中的属性值通过IOC容器进行注入,这种方式成为依赖注入

依赖注入的方式有三种
1.属性注入
通过setter方法注入

在xml中通过使用property标签来注入,其中name属性是对象中的属性名,
value是属性值。



<property name=“age” value=“20" >

集合使用list标签完成装配










2.构造器注入

通过构造方法注入,可以在创建对象时就注入属性值。
•在xml中通过使用constructor-arg标签来注入。





•在User类中需要创建一个对应的构造方法

通过index属性指定参数的顺序

<constructor-arg value="1“ index=“0”>
<constructor-arg value="张三“index=“1” >
<constructor-arg value="20“ index=“2” >

通过类型来匹配参数。




字面值:可以通过value属性或value标签来注入。
若字面值包含特殊字符,可以用<![CDATA[]]>将字面值包裹起来

<![CDATA[]]>


20

引用其他Bean

Bean对象中的属性不仅仅是基本类型或字符串,还有可能是其他Bean对象。
在XML文件中使用ref来引用其他Bean对象。








3.工厂方法注入

注入Properties集合

使用props标签来注入java.util.Properties对象,prop是子标签,每个
子标签必须定义key属性。



root
123456
jdbc:mysql://localhost:3306/demo
<prop key=“driverclass">org.gjt.mm.mysql.Driver


使用外部属性文件

Spring提供了BeanFactory的一个后置处理器
PropertyPlaceholderConfigurer来读取外部属性文件,在Bean配置文件中
使用${属性名}来访问对应的值。

通过context:property-placeholder来加载外部文件

<context:property-placeholder location=“classpath:db.properties”/>



d b u s e r < / p r o p > < p r o p k e y = " d b p a s s " > {dbuser}</prop> <prop key="dbpass"> dbuser</prop><propkey="dbpass">{dbuser}
d b u r l < / p r o p > < p r o p k e y = " d r i v e r c l a s s " > {dburl}</prop> <prop key="driverclass"> dburl</prop><propkey="driverclass">{driverclass}


基于注解装配Bean
Spring提供了以下几个注解来完成Bean的自动装配
@Autowired
作用:装配Bean
用法:配置在属性,set方法,构造方法上
按类型装配依赖对象,如果有多个类型则按名称匹配。默认
情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性
为false。

@Qualifier
配合@Autowired使用。把按类型配置变为按名称匹配
用法:配置在属性,set方法上

@Resource
作用:装配Bean
用法:配置在属性,set方法上
@Resource注解默认按名称装配。名称可以通过name属性指定,如果没有指定name属性,默认取属性的名称作为bean名称寻找依赖对象。

@PostConstruct
指定初始化方法
初始化方法在容器产生Bean对象的时候被调用

@PreDestory
销毁方法
销毁方法在容器主动调用销毁的时候被调用

需要在xml文件中加入
context:annotation-config</context:annotation-config>

配置类中的自动扫描

@ComponentScan用于指定扫描的包
@Component用于标识需要装配的类

指定从哪个类所在的包开始扫描
@ComponentScan(basePackageClasses = ApplicationLauncher.class)
指定扫描的起始包
@ComponentScan(basePackages = “Application”)

SpringMVC

spring MVC是一个基于MVC模式的表现层框架,和其他的MVC表现层框架,有如下特点:

  • 基于的是Servlet模式
  • 控制器不在需要继承其他的类,只需要用@Controller注解
  • 应用控制器方法参数封装灵活,如果方法参数和表单数据键相同,由前端控制器完成封装
  • 返回页面直接在方法中指定,可以String,void等
  • 性能优秀

MVC模式:Model-View-Controller(模型-视图-控制器)模式,它是一种架构模式,其目标是软件的用户界面和业务逻辑分开,使得代码更高的可拓展性、可复用性、可维护性等。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cYKlFK9E-1665151185193)(C:\Users\meme\Desktop\MVC模式.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-goEi33Xz-1665151185193)(C:\Users\meme\Desktop\MVC和三层.jpg)]

控制器

SpringMVC 围绕DispatcherServlet设计的,DispatcherServlet用来处理所有HTTP请求和响应。

解决了原本使用Serlvet处理请求,可能出现类爆炸的情况,一个Servlet只能处理一个请求,如果请求过多,100甚至1000个,我们需要提供100个甚至1000个Serlvet类。

前端控制器(DispatcherServlet):负责接收客户端的请求,根据请求路径访问应用控制器,负责把页面参数填充给JavaBean,负责转发页面等。

应用控制器(用户自定义含有@Controller注解的类),负责产生业务组件,调用业务组件方法完成业务,根据结果返回转发的页面对象。

Spirng MVC的工作流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vgiGQE15-1665151185194)(C:\Users\meme\Desktop\Spring工作流程.jpg)]

1.客户端向服务器发出请求时,服务器先使用前端控制器(DIspatcherServlet)接收请求

2.前端控制器会根据请求的URL路径,定位到具体的应用控制器(Controller)中具体的方法,并封装好的实体对象传入应用控制器方法

3.在方法中生成业务组件调用组件的业务方法,把处理结果(模型),返回给转发的页面路径。由前端控制器(DIspatcherServlet)完成页面转发。

SpringMVC环境的搭建

1.导入SpringMVC依赖

<!-- Spring 核心-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>

        <!-- MVC-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <!--tomcat-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>9.0.36</version>
        </dependency>

2.提供SpringMVC配置类

@Configuration
@ComponentScan(basePackageClasses = WebApplicationConfig.class)
@EnableWebMvc // 开启类型的自动转换
public class WebApplicationConfig implements WebMvcConfigurer {

    // 请求映射处理适配器
    @Autowired
    private RequestMappingHandlerAdapter adapter;

    // 设置响应信息的编码集
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        StringHttpMessageConverter stringHttpMessageConverter
                = (StringHttpMessageConverter)converters.get(1);
        stringHttpMessageConverter.setDefaultCharset(Charset.forName("utf-8"));
    }

    // 提供静态资源的支持 请求的url以/html/开头,表示找类路径的/static/html/下的文件
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/html/**")
                .addResourceLocations("classpath:/static/html/");
    }

    // 注册类型转换器
    @PostConstruct
    public void addConversionConfig() {
        ConfigurableWebBindingInitializer initializer =
                (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer();
        if (initializer.getConversionService() != null) {
            GenericConversionService converService = (GenericConversionService) initializer.getConversionService();
            // 添加自定义转换器
            converService.addConverter(new LocalDateTypeChange());
        }
    }


}

类型转换器

import org.springframework.core.convert.converter.Converter;
			// 第一个位置:表单元素提供的数据类型,第二个位置:需要转换的目标类型
public class LocalDateTypeChange implements Converter<String, LocalDate> {
    @Override
    public LocalDate convert(String s) {
        if(s != null && s.matches("\\d{4}-\\d{2}-\\d{2}")){
            return LocalDate.parse(s);
        }
        return null;
    }
}

3.根据配置类在Tomcat容器中去创建并注册前端控制器(DispatcherServlet)

public class MainServer {
    public MainServer(){
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);
        tomcat.getConnector();

        Context context = tomcat.addContext("",null);

        // 创建前端控制器
        DispatcherServlet dispatcherServlet =
                new DispatcherServlet(
                        this.createApplicationContext(context.getServletContext())
                );

        // 注册前端控制器
        Wrapper servlet =
                Tomcat.addServlet(context,"dispatcherServlet",
                        dispatcherServlet);
        servlet.setLoadOnStartup(1);
        // 表示任何的路径请求都可以到达前端控制器
        servlet.addMapping("/*");

        try {
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }

    }

    /**
     * 创建SpringMVC的应用上下文对象
     * @param servletContext servlet 上下文对象
     * @return SpringMVC的应用上下文对象
     */
    public WebApplicationContext createApplicationContext(ServletContext servletContext){
        AnnotationConfigWebApplicationContext ctx =
                new AnnotationConfigWebApplicationContext();
        // 注入配置类
        ctx.register(WebApplicationConfig.class);
        ctx.setServletContext(servletContext);

        ctx.refresh();
        // 用于在非web应用中关闭IoC容器
        ctx.registerShutdownHook();
        return ctx;
    }

    public static void main(String[] args) {
        new MainServer();
    }

}

5.根据需求提供应用控制器(带有@Controller的类)

@Controller
public class TestController {

    // RequestMapping 书写请求映射路径
    // 当以该注解的映射路径访问前端控制器时会转发到对应映射路径的方法
    // 方式1:通过RequestMapping 来设置MIME类型 produces = "text/html;charset=utf-8"
    @RequestMapping("/test")
    public String test(){
        System.out.println("应用控制器的test方法");
        /* 请求转发工作流程:
        客户端向服务器发出请求,服务器在服务器内部进行资源的调配,将客户端想要的资源回发给客户端。
        客户端只向服务器发出一次请求,可以共享request中绑定的数据
         */
        return "/html/Test.html";
    }

    @RequestMapping("/test3")
    public String test3(){
        System.out.println("应用控制器的test方法");
        /* 重定向工作流程:
          客户端向服务器发起请求,服务器在重定向资源时,向客户端发送302状态码,同时发送location响应头。
          客户端接收到响应信息后,发现为302状态码,就会读取location响应头信息,根据该信息的路径,再次向
          服务器发出第二次请求
         */
        return "redirect:/html/Test.html";
    }


    @RequestMapping("/test2")
    @ResponseBody // 把JSON或XML或普通文本写入HttpServletOutStream
    public String test2(){
        System.out.println("应用控制器的test2方法");
        return "测试2";
    }

    @RequestMapping("/addUser")
    @ResponseBody
    public String addUser(UserBean userBean,int age,String tel,
                          @RequestParam("tel") String userTel){
        /*
         如果表单元素的name属性值和控制器方法的参数名不同,可以通过
         注解@RequestParam 对方法参数指定它对应的表单元素
         */

        System.out.println(userBean);
        System.out.println(age);
        System.out.println(tel);
        System.out.println(userTel);
        return "添加成功";
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值