Spring

在这里插入图片描述


除了自己,没人可以为快乐负责

Spring

1.spring的优势
  • 方便解耦,简化开发通过Spring提供的 loC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

  • Aop编程的支持通过Spring的AOP功能,方便进行面向切面编程,许多不容易用传统ОOP实现的功能可以通过AOP轻松实现。

  • 声明式事务的支持可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务管理,提高开发效率和质量。

  • 简单的步骤

    导入Spring开发的基本包坐标
    编写 Dao接口和实现类
    创建Spring核心配置文件
    在Spring配置文件中配置UserDaolmpl
    使用Spring的API获得Bean 实例
2.初识控制反转

将创建类的对象的权利交给容器

配置文件
<bean id="dao"/**唯一标识**/ class="spring.Dao.impl.Daoimpl/**类的全包名**/"></bean>

demo类中
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
Daoimpl dao = (Daoimpl) app.getBean("dao");
        dao.run();

Bean标签的其他属性 :scope

scope
singleton默认,单例的; 当bean是单例模式的时候,在加载配置文件的时候spring容器就已经给所有是单例模式的类创建了一个对象
prototype多例的 ;当bean是多例模式的时候,只有在用户getBean的时候才会创建一个对象
requestWEB项目中,Spring创建一个Bean的对象,将对象存入到request 域中
sessionWEB项目中,Spring创建一个Bean的对象,将对象存入到session 域中
global sessionwEB项目中,应用在Portlet环境,如果没有Portlet环境那么globalSession相当于session

Bean标签的生命周期属性配置

  • init-method:指定被管理的类的初始化方法
  • destory-method:指定被管理的类的销毁方法,不过需要手动关闭不然会来不及执行

Bean实例化的三种方式

  • 无参构造方法实例化

  • 工厂静态方法实例化

    public class Daoimpl implements springDao {
        public void run() {
            System.out.println("dao运行起来了");
        }
        public static Daoimpl factoryDao(){
            return new Daoimpl();//这是静态工厂方法
        }//当然这里也可以是其他类的静态方法返回当前类的实例对象,如jdbc的getConnection等等
    }
    
    配置文件
    <bean id="dao" class="spring.Dao.impl.Daoimpl" factory-method="factoryDao"></bean>
    
  • 工厂实例方法实例化

    public class Daoimpl implements springDao {
        public void run() {
            System.out.println("dao运行起来了");
        } 
    }
    public class Daofactory {
        public Daoimpl factoryDao(){
            System.out.println("工厂静态方法");
            return new Daoimpl();
        }
    }
    !!!!这个时候工厂方法不能放在需要创建的类里面,因为如果放里面的话,要求先有实例才能调用工厂方法,而第一个实例只能由构造函数创建
        
    ps:这里与静态方法不同的是,必须先拥有当前对象才能调用对象的工厂方法
        
     配置文件
    <bean id="daofactory" class="spring.Dao.impl.Daofactory"></bean>//因为不是静态方法所以要先创建工厂类的实例对象,
    <bean id="dao" class="spring.Dao.impl.Daoimpl" factory-bean="daofactory" factory-method="factoryDao" ></bean>
    
依赖注入
  • 在不使用依赖注入的方式的时候,要搭建三层架构,是在serive层由程序员向spring容器要dao层实例,而在web层又向spring容器要service层实例

使用依赖注入的方式,因为service和dao都在Spring容器之中,而程序只需要service,所以在spring容器中,将dao层直接设置到service层内部

两种方式

  • set方法

    配置文件
       <bean id="dao" class="spring.Dao.impl.Daoimpl"></bean>
        <bean id="service" class="spring.Servive.impl.ServiceImpl">
            <property name="daoo"/**构造方法去掉set首字母小写**/ 
                       ref="dao"/**引用dao唯一id**/>
            </property>
        </bean>
    ------------------------
      service层
      public class ServiceImpl implements springService {
        private Daoimpl dao;
    
        public void setDaoo(Daoimpl dao) {
            this.dao = dao;
        }
        public void save() {
            System.out.println("service开始运行dao");
            dao.run();
        }
    }
    -----------
        web层用getBean只调用service就行了
    

    简化配置文件引入p命名空间

    <bean id="dao" class="spring.Dao.impl.Daoimpl"></bean>
        <bean id="service" class="spring.Servive.impl.ServiceImpl" p:daoo-ref="dao">
        </bean>
    
  • 构造方法

    <bean id="service" class="spring.Servive.impl.ServiceImpl">
         <constructor-arg name="dao"/**构造函数的参数名**/ ref="dao"></constructor-arg>
      </bean>
     ------------
      service层
        同上加一个有参构造方法
        public ServiceImpl(Daoimpl dao) {
            this.dao = dao;
        }
    

其他数据类型的注入

  • 普通数据类型

    配置文件
    <bean id="service" class="spring.Servive.impl.ServiceImpl" p:daoo-ref="dao" p:username="雷锋">
      </bean>
        ----------------
     private String username;service类的成员变量
    
  • 引用或者集合数据类型

    配置文件
    <bean id="service" class="spring.Servive.impl.ServiceImpl" p:daoo-ref="dao" p:username="雷锋" >
            <property name="list">
                <list>
                    <value>aaa</value>
                    <value>bbb</value>
                </list>
            </property>
        </bean>
      ----------
        private ArrayList list;
    
相关API
  • ApplicationContext的实现类

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rujxkCwn-1661235847068)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220719232841773.png)]

  • getBean

    参数 id或者类的class字节码文件

    如果一个类只会使用一个而不是多个可以使用类的class参数,反之不行

配置数据源
C3p0的配置
------
不使用依赖之前的代码
ComboPooledDataSource c3 = new ComboPooledDataSource();
        c3.setDriverClass("com.mysql.jdbc.Driver");
        c3.setJdbcUrl("jdbc:mysql://localhost:3306/zf1");
        c3.setUser("root");
        c3.setPassword("root");
        Connection connection = c3.getConnection();
        System.out.println(connection);
---------------------
  配置文件
    <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/zf1"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
        
  -----------------
   spring容器加载properties文件
     <context:properties-placeholder location="xx.properties" />
      <bean
         <property name="xxx" value='${key}'
      </bean>
注解开发
  • Spring原始注解

    注解说明
    @Component使用在类上用于实例化Bean
    @Controller使用在web层类上用于实例化Bean使用
    @Service在service层类上用于实例化Bean使用
    @Repository在dao层类上用于实例化Bean
    @Autowired使用在字段上用于根据类型从spring容器中进行依赖注入
    @Qualifier必须结合@Autowired—起使用用于根据唯一id进行依赖注入
    @Resource相当于@Autowired+@Qualifier,按照唯一id进行注入
    @Value注入普通属性,通常配合${key}使用
    @Scope标注Bean的作用范围
    @PostConstruct使用在方法上标注该方法是Bean的初始化方法
    @PreDestroy使用在方法上标注该方法是Bean的销毁方法
  • 新注解

    注解说明
    @Configuration用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解
    @ComponentScan用于指定Spring在初始化容器时要扫描的包作用一样
    @Bean一样使用在方法上,标注将该方法的返回值存储到Spring容器中
    @PropertySource用于加载.properties文件中的配置
    @Import用于导入其他配置类

    配置抽取为配置类

    @PropertySource("jdbc.properties")
    @ComponentScan("spring")
    @Configuration
    public class configs {
        @Value("${driverClassName}")
        private String ClassName;
        @Value("${url}")
        private String Url;
        @Value("${jdbcusername}")
        private String userName;
        @Value("${password}")
        private String password;
        private DruidDataSource dataSource;
        @Bean("datasource")
        public DataSource getDataSource(){
            dataSource = new DruidDataSource();
            dataSource.setDriverClassName(ClassName);
            dataSource.setUrl(Url);
            dataSource.setUsername(userName);
            dataSource.setPassword(password);
            return dataSource;
        }
    }
    
spring集成web
初识
ApplicationContext app = new AnnotationConfigApplicationContext("spring");
 Serviceimpl service = app.getBean(Serviceimpl.class);
  service.save();
------//当spring在web的三层架构之中运行的时ApplicationContext app = new AnnotationConfigApplicationContext("spring");
 Serviceimpl service = app.getBean(Serviceimpl.class);
  service.save();
------//当spring在web的三层架构之中运行的时候,在web层按照以往的知识都会写出如上代码
  ApplicationContext又叫做应用上下文对象,如果太多的如上代码就会造成配置文件被加载多次,应用上下文对象被创建多次
---------解决方法:定义一个servlet监听器,
    public class springTestListen implements ServletContextListener {
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ApplicationContext app = new AnnotationConfigApplicationContext("spring");
        /**对于上述的参数也可以抽成配置文件,web.xml是一个好的选择,在servlet初始化参数可以配置创建spring容器要传递的参数***/
        ServletContext servletContext = servletContextEvent.getServletContext();
        servletContext.setAttribute("app",app);
    }
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }
}

----------------官方提供的
    1.配置ContextLoaderListener(官方提供)
        在web.xml中配置监听器
        <context-param>
        <param-name>
            contextConfigLocation
        </param-name>
        <param-value>
            classpath:**/*Context.xml
        </param-value>
      </context-param>
            <listener>
                <listener class>org.springframework.web.context.ContextLoaderListener</listener-class>
            </listener>***/
 --------java类方式配置--------------------------------------------
           ps. 使用类继承WebApplicationInitializer
   public class springTestListen implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext Context) throws ServletException {
        Context.addListener(new ContextLoaderListener());
//        Context.addListener(new WebAppRootListener());
        Context.setInitParameter("contextConfigLocation", "classpath:**/*Context.xml");
    }
}
    2.使用WebApplicationContextUtils获取应用上下文对象
    
 -----------------------无xml配置
 
  2.无xml的方式也不应该加载applicationContext.xml
-----java类方式---------------
   public class springTestListen implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext Context) throws ServletException {
//        AnnotationConfigWebApplicationContext app = new AnnotationConfigWebApplicationContext();
//        app.register(configs.class);
//        app.setServletContext(Context);
        Context.addListener(new ContextLoaderListener());
        Context.addListener(new WebAppRootListener());
//        Context.setInitParameter("contextConfigLocation", "classpath:**/*Context.xml");
        Context.setInitParameter("contextClass", "org.springframework.web.context.support.AnnotationConfigWebApplicationContext");
        Context.setInitParameter("contextConfigLocation","spring.config.configs");
    }
}
------------web.xml(二选一)
   ntext-param>
            <param-name>contextClass</param-name>
            <param-value>
                org.springframework.web.context.support.AnnotationConfigWebApplicationContext
            </param-value>
       </context-param>
        <context-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>spring.config.configs</param-value>
        </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
springMvc

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9e3wV1VX-1661235847069)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220719093026744.png)]

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mhi5RrqR-1661235847069)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220725133119911.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A83Yf1Rv-1661235847069)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220726170930816.png)]

springMvc常用注解
注解
@RequestMapping作用:用于建立请求URL和处理请求方法之间的对应关系位置, 1.类上,请求URL的第一级访问目录。此处不写的话,就相当于应用的根目录; 2.方法上,请求URL的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径属性; 3.value:用于指定请求的URL。它和path属性的作用是一样的method:用于指定请求的方式 4.params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样例如:
@RequestBody@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的),所以只能发送POST请求。 GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。

在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
  • springMvc.xml其他配置

  • 在spring-webmvc的jar包下面有一个DispatcherServlet.properties配置着默认的DispatcherServlet需要的组件如视图解析器,适配器等等

    web.xml方式配置dispatcher
    <servlet>
            <servlet-name>Diaspacter</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:*mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Diaspacter</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    

    1前端控制器 DispatcherServlet

    • 静态资源的处理

      浏览器的请求到达Tomcat的时候发现有一个servlet为dispatcherServlet,会拦截所有请求,转到普通的controller,这时候要访问静态资源就应该配置
      < m v c : r e s o u r c e m a p p i n g = " / j s / ∗ ∗ " l o c a t i o n = " / j s / " / > 或者 < m v c : d e f a u l t − s e r v l e t − h a n d l e r / > <mvc:resource mapping="/js/**" location="/js/" /> 或者 <mvc:default-servlet-handler /> <mvc:resourcemapping="/js/"location="/js/"/>或者<mvc:defaultservlethandler/>

    2处理器映射器 HandlerMapping

    3处理器适配器 HandlerAdapter

    4处理器 Handler

    5视图解析器 View Resolver

    6视图 View

    • 数据响应:

    • 1.直接返回字符串

    • 2.返回ModelAndView对象

      @RequestMapping("/b")
          public ModelAndView run1(/**或者将Mv模型视图加入参数,容器会根据参数自动注入*/){
              ModelAndView MV = new ModelAndView();
              //将数据添加到模型的域中
               MV.addObject("shujv","niaho");
              //设置视图名称
              MV.setViewName("success.jsp");
              return MV;
          }
      
    • 回写数据

      • 1.原生回写数据

        @RequestMapping("/d")
            public void run2(HttpServletResponse resp) throws IOException {
                resp.setCharacterEncoding("GBK");
                resp.getWriter().print("原生回写数据");
            }
        
      • 2.加注解ResponseBody告知框架,方法返回的字符串不是跳转而是直接在http响应体中返回

      • 3.返回对象或者集合,配置处理器适配器告知转化为json

        <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
            <property name="messageConverters">
                <list>
                    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
                </list>
            </property>
        </bean>
        
获取请求参数

普通类型的请求参数

@RequestMapping("/d")
    @ResponseBody
    public void run2(String username,String age) throws IOException {
        System.out.println(username);
        System.out.println(age);
    }
-----------------------
  @RequestParam
    如果前端的参数的名字  name想要绑定到username上,
     public void run2(@RequestParam(value="name" require=false默认为true)String username,String age) throws IOException

获取POJO类型的参数

//---实体类
public class userBean {
    private String username;
    private String password;
}
http://localhost:8080/find?username=zhangfeng&age=11
@RequestMapping("/d")
    @ResponseBody
    public void run2(userBean user) throws IOException {
        System.out.println(user);
    }

获得数组类型的参数

http://localhost:8088/list?string=a&string=2&string=t

@RequestMapping("/list")
    @ResponseBody
    public void run3(String[] string)  {
        System.out.println(Arrays.asList(string));
    }

获取集合类型的参数 涉及到json需要自己导包,再配置处理适配器

1.了解
   封装为VO对象,集合作为VO类的一个属性
2.当使用Ajax提交的时候,可以指定contentType为json形式,在方法参数的位置使用@RequestBody可以直接接受集合数据而无需使用POJO包装
   @RequestMapping("/list")
    @ResponseBody
    public void run4(@RequestBody List<userBean> user)  {
        System.out.println(user);
    }
    //请求参数 
        [
            {
                "username": "xxx",
                "password": "14"
            },
            {
                "username": "xxx2",
                "password": "15"
            }
        ]
不管是接受json还是发送json都需要自己配置导包
拦截器

步骤

  • 自定义拦截器类实现HandlerInterceptor接口

    //在目标执行之前
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            return false;
        }
    //该方法是在当前请求进行处理之后被调用,前提是preHandle方法的返回值为true 时才能被调用,且它会在DispatcherServlet进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            
        }
    //在流程执行完毕之后执行
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            
        }
    
  • 配置

    <mvc:interceptors>
        <mvc:interceptor>
          <mvc:mapping path="/*"/>
          <bean class="web.interCeptor.myInterceptor(自定义的拦截器的全类名)"></bean>
        </mvc:interceptor>
      </mvc:interceptors>
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值