no12-第十章第一次-项目框架升级之单例模式

飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

分类: ssm 专栏: ssm框架课 标签: 单例模式

2022-12-27 15:52:45 1107浏览

单例模式学习

1.单例模式

1.1使用单例模式改造数据库连接功能

/**
 * 懒汉模式
 * 时间换空间(getInstance的时候才实例化)
 * 缺点:1有线程安全的问题
 * 2.解决方法是加同步锁
 */
public  class ConfigManager  {

    private static ConfigManager configManager ;
    private Properties properties;

    private ConfigManager()  {
        System.out.println("exec ConfigManager()...");
        String configFile="database.properties";
        InputStream is= ConfigManager.class.getClassLoader().getResourceAsStream(configFile);
        properties = new Properties();
        try {
            properties.load(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //对外提供获取ConfigManager实例的方式
    public  static ConfigManager getInstance(){
        if(configManager == null){
            configManager= new ConfigManager();
        }
        return configManager;
    }

    //读取配置文件的值( 根据键值对)——这是一个普通的成员方法不是静态方法。
    public  String getValue(String key){
        return properties.getProperty(key);
    }
}

1.2懒汉模式和饿汉模式

1.懒汉模式:

线程不安全(加同步锁synchronized的方式虽然可以解决这个问题但消耗了性能)

上面读取数据库配置文件的类就是采用的懒汉模式。以下是测试类——用来验证线程不安全的问题

public class TestUser
{
    public static void main(String[] args) {
        ConfigManager configManager=ConfigManager.getInstance();
        System.out.println(configManager.getValue("url"));


        System.out.println("================");
        ConfigManager configManager2=ConfigManager.getInstance();
        System.out.println(configManager2.getValue("url"));


//        MyThread myThread = new MyThread();
//        Thread thread1=new Thread(myThread);
//        thread1.start();
//
//        Thread thread2=new Thread(myThread);
//        thread2.start();

    }

}
class MyThread implements Runnable {

    @Override
    public void run() {
        ConfigManager configManager=ConfigManager.getInstance();
        System.out.println(configManager.getValue("url"));
    }
}

为了直观测试出线程不安全的情景,这里最好是让主线程也睡几秒

image.png

image.png

2.饿汉模式

/**
 * 饿汉模式(空间换时间)
 * 1.没有线程安全的问题
 * 2.因为不需要加同步锁,所以也不存在性能问题
 *
 * 缺点:没有延迟加载的特性
 */
public  class ConfigManager2 {


    private static ConfigManager2 configManager = new ConfigManager2();
    private Properties properties;

    private ConfigManager2()  {
        System.out.println("exec ConfigManager()...");
        String configFile="database.properties";
        InputStream is= ConfigManager2.class.getClassLoader().getResourceAsStream(configFile);
        properties = new Properties();
        try {
            properties.load(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //对外提供获取ConfigManager实例的方式
    public  static  ConfigManager2 getInstance(){

        return configManager;
    }

    //读取配置文件的值( 根据键值对)——这是一个普通的成员方法不是静态方法。
    public  String getValue(String key){
        return properties.getProperty(key);
    }


    /**
     * 用来测试是否具备延迟加载的特性
     */
    public static void   testYan(){
        System.out.println("exec testYan()...");
    }
}

3.静态内部类

/**
 * 使用静态内部类的方式改造
 * 1.有延迟加载的特性
 * 2.没有线程安全问题
 * 3.没有性能问题,方法上没加锁
 */
public  class ConfigManager3 {


    private static ConfigManager3 configManager ;
    private Properties properties;

    private ConfigManager3()  {
        System.out.println("exec ConfigManager()...");
        String configFile="database.properties";
        InputStream is= ConfigManager3.class.getClassLoader().getResourceAsStream(configFile);
        properties = new Properties();
        try {
            properties.load(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //对外提供获取ConfigManager实例的方式
    public  static ConfigManager3 getInstance(){
        configManager=ConfigManager3Helper.helper;
        return configManager;
    }

    //静态内部类
    public static class ConfigManager3Helper{
            static ConfigManager3 helper = new ConfigManager3();
    }

    //读取配置文件的值( 根据键值对)——这是一个普通的成员方法不是静态方法。
    public  String getValue(String key){
        return properties.getProperty(key);
    }


    /**
     * 用来测试是否具备延迟加载的特性
     */
    public static void   testYan(){
        System.out.println("exec testYan()...");
    }
}

1.3springMVC框架中的单例模式

spring框架ioc容器默认就是单例模式

2.搭建项目运行环境

目前是spring和springmvc整合

  1. 引入相应的jar包
  2. 编写applicationCotext配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">


    <context:component-scan base-package="cn.smbms.dao,cn.smbms.service"/>
</beans>
  1. 编写springmvc的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--扫描control包-->
    <context:component-scan base-package="cn.smbms.controller"/>

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--开启springmvc注解驱动-->
    <mvc:annotation-driven/>
    <mvc:default-servlet-handler/>

</beans>
  1. 把control层 service层 dao层加上注解
  2. 修改web.xml初始化spring和springmvc的配置
 <!--初始化spring的相关配置-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--初始化springmvc的相关配置-->
    
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springnvc.xml</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!--解决中文乱码问题-->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

3.改造登录、注销功能

3.1登录功能的初步改造

3.2静态资源文本的引用

静态资源访问不到的问题解决:

    <!--放行静态资源:方法一-->
<!--    <mvc:resources mapping="/static/*" location="/static/"/>-->
<!--    <mvc:resources mapping="/js/*" location="/js/"/>-->
<!--    <mvc:resources mapping="/css/*" location="/css/"/>-->

    <!--放行静态资源:方法二-->
    <mvc:default-servlet-handler/>

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695