diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 27494e7..b83c769 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -1024,7 +1024,8 @@ function drupal_bootstrap($phase = NULL) {
 
       switch ($current_phase) {
         case DRUPAL_BOOTSTRAP_CONFIGURATION:
-          $kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod');
+          $classloader = require __DIR__ . '/../vendor/autoload.php';
+          $kernel = DrupalKernel::createFromRequest($request, $classloader, 'prod');
           break;
 
         case DRUPAL_BOOTSTRAP_KERNEL:
@@ -1399,50 +1400,6 @@ function _current_path($path = NULL) {
 }
 
 /**
- * Initializes and returns the class loader.
- *
- * The class loader is responsible for lazy-loading all PSR-0 compatible
- * classes, interfaces, and traits (PHP 5.4 and later). It's only dependency
- * is DRUPAL_ROOT. Otherwise it may be called as early as possible.
- *
- * @param $class_loader
- *   The name of class loader to use. This can be used to change the class
- *   loader class when calling drupal_classloader() from settings.php. It is
- *   ignored otherwise.
- *
- * @return \Composer\Autoload\ClassLoader
- *   A ClassLoader class instance (or extension thereof).
- */
-function drupal_classloader($class_loader = NULL) {
-  // By default, use the ClassLoader which is best for development, as it does
-  // not break when code is moved on the file system. However, as it is slow,
-  // allow to use the APC class loader in production.
-  static $loader;
-
-  if (!isset($loader)) {
-
-    // Retrieve the Composer ClassLoader for loading classes.
-    $loader = include __DIR__ . '/../vendor/autoload.php';
-
-    // Register the class loader.
-    // When configured to use APC, the ApcClassLoader is registered instead.
-    // Note that ApcClassLoader decorates ClassLoader and only provides the
-    // findFile() method, but none of the others. The actual registry is still
-    // in ClassLoader.
-    if (!isset($class_loader)) {
-      $class_loader = Settings::get('class_loader', 'default');
-    }
-    if ($class_loader === 'apc') {
-      require_once __DIR__ . '/../vendor/symfony/class-loader/Symfony/Component/ClassLoader/ApcClassLoader.php';
-      $apc_loader = new ApcClassLoader('drupal.' . Settings::getHashSalt(), $loader);
-      $loader->unregister();
-      $apc_loader->register();
-    }
-  }
-  return $loader;
-}
-
-/**
  * Registers an additional namespace.
  *
  * @param string $name
@@ -1451,7 +1408,7 @@ function drupal_classloader($class_loader = NULL) {
  *   The relative path to the Drupal component in the filesystem.
  */
 function drupal_classloader_register($name, $path) {
-  $loader = drupal_classloader();
+  $loader = \Drupal::service('kernel')->getClassLoader();
   $loader->addPsr4('Drupal\\' . $name . '\\', DRUPAL_ROOT . '/' . $path . '/src');
 }
 
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 4cdc529..af06e74 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -358,7 +358,8 @@ function install_begin_request(&$install_state) {
   }
 
   // Only allow dumping the container once the hash salt has been created.
-  $kernel = InstallerKernel::createFromRequest($request, drupal_classloader(), $environment, (bool) Settings::get('hash_salt', FALSE));
+  $classloader = require __DIR__ . '/../vendor/autoload.php';
+  $kernel = InstallerKernel::createFromRequest($request, $classloader, $environment, (bool) Settings::get('hash_salt', FALSE));
   $kernel->setSitePath($site_path);
   $kernel->boot();
   $container = $kernel->getContainer();
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 7b69341..6c457bd 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -225,10 +225,7 @@ public static function createFromRequest(Request $request, ClassLoader $class_lo
    * @param string $environment
    *   String indicating the environment, e.g. 'prod' or 'dev'.
    * @param \Composer\Autoload\ClassLoader $class_loader
-   *   (optional) The class loader is only used if $storage is not given or
-   *   the load from storage fails and a container rebuild is required. In
-   *   this case, the loaded modules will be registered with this loader in
-   *   order to be able to find the module serviceProviders.
+   *   The class loader to use.
    * @param bool $allow_dumping
    *   (optional) FALSE to stop the container from being written to or read
    *   from disk. Defaults to TRUE.
@@ -349,8 +346,6 @@ public function boot() {
     // Start a page timer:
     Timer::start('page');
 
-    drupal_classloader();
-
     // Load legacy and other functional code.
     require_once DRUPAL_ROOT . '/core/includes/common.inc';
     require_once DRUPAL_ROOT . '/core/includes/database.inc';
@@ -410,6 +405,21 @@ public function getContainer() {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function getClassloader() {
+    return $this->classLoader;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setClassloader($classloader) {
+    $this->classloader = $classloader;
+    return $this;
+  }
+
+  /**
    * Helper method that does request related initialization.
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
diff --git a/core/lib/Drupal/Core/DrupalKernelInterface.php b/core/lib/Drupal/Core/DrupalKernelInterface.php
index 08d007c..7a3219e 100644
--- a/core/lib/Drupal/Core/DrupalKernelInterface.php
+++ b/core/lib/Drupal/Core/DrupalKernelInterface.php
@@ -57,6 +57,27 @@ public function getServiceProviders($origin);
   public function getContainer();
 
   /**
+   * Gets the classloader of the kernel.
+   *
+   * @return mixed
+   *   The classloader. Usually an instance of \Composer\Autoload\Classloader or
+   *   \Symfony\Component\ClassLoader\ApcClassLoader.
+   */
+  public function getClassLoader();
+
+  /**
+   * Sets the classloader of the kernel.
+   *
+   * @param mixed $classloader
+   *   The classloader to set. Usually an instance of
+   *   \Composer\Autoload\Classloader or
+   *   \Symfony\Component\ClassLoader\ApcClassLoader.
+   *
+   * @return $this
+   */
+  public function setClassLoader($classloader);
+
+  /**
    * Set the current site path.
    *
    * @param $path
diff --git a/core/modules/simpletest/src/InstallerTestBase.php b/core/modules/simpletest/src/InstallerTestBase.php
index 34354a5..7b57987 100644
--- a/core/modules/simpletest/src/InstallerTestBase.php
+++ b/core/modules/simpletest/src/InstallerTestBase.php
@@ -150,7 +150,8 @@ protected function setUp() {
     // WebTestBase::tearDown() will delete the entire test site directory.
     // Not using File API; a potential error must trigger a PHP warning.
     chmod(DRUPAL_ROOT . '/' . $this->siteDirectory, 0777);
-    $this->kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod', FALSE);
+    $classloader = require __DIR__ . '/../../../vendor/autoload.php';
+    $this->kernel = DrupalKernel::createFromRequest($request, $classloader, 'prod', FALSE);
     $this->kernel->prepareLegacyRequest($request);
     $this->container = $this->kernel->getContainer();
     $config = $this->container->get('config.factory');
diff --git a/core/modules/simpletest/src/KernelTestBase.php b/core/modules/simpletest/src/KernelTestBase.php
index 616d064..f7b04c5 100644
--- a/core/modules/simpletest/src/KernelTestBase.php
+++ b/core/modules/simpletest/src/KernelTestBase.php
@@ -154,7 +154,8 @@ protected function setUp() {
     // Back up settings from TestBase::prepareEnvironment().
     $settings = Settings::getAll();
     // Bootstrap a new kernel. Don't use createFromRequest so we don't mess with settings.
-    $this->kernel = new DrupalKernel('testing', drupal_classloader(), FALSE);
+    $classloader = require __DIR__ . '/../../../vendor/autoload.php';
+    $this->kernel = new DrupalKernel('testing', $classloader, FALSE);
     $request = Request::create('/');
     $this->kernel->setSitePath(DrupalKernel::findSitePath($request));
     $this->kernel->boot();
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 89ff9db..744bb5c 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -877,7 +877,8 @@ protected function setUp() {
     chmod($directory, 0777);
 
     $request = \Drupal::request();
-    $this->kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod', TRUE);
+    $classloader = require __DIR__ . '/../../../vendor/autoload.php';
+    $this->kernel = DrupalKernel::createFromRequest($request, $classloader, 'prod', TRUE);
     $this->kernel->prepareLegacyRequest($request);
     // Force the container to be built from scratch instead of loaded from the
     // disk. This forces us to not accidently load the parent site.
diff --git a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
index a36adae..a25c9e2 100644
--- a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
+++ b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\Site\Settings;
-use Drupal\simpletest\DrupalUnitTestBase;
+use Drupal\simpletest\KernelTestBase;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -17,12 +17,7 @@
  *
  * @group DrupalKernel
  */
-class DrupalKernelTest extends DrupalUnitTestBase {
-
-  /**
-   * @var \Composer\Autoload\ClassLoader
-   */
-  protected $classloader;
+class DrupalKernelTest extends KernelTestBase {
 
   protected function setUp() {
     // DrupalKernel relies on global $config_directories and requires those
@@ -38,8 +33,6 @@ protected function setUp() {
       'directory' => DRUPAL_ROOT . '/' . $this->public_files_directory . '/php',
       'secret' => Settings::getHashSalt(),
     )));
-
-    $this->classloader = drupal_classloader();
   }
 
   /**
@@ -59,7 +52,8 @@ protected function setUp() {
    */
   protected function getTestKernel(Request $request, array $modules_enabled = NULL, $read_only = FALSE) {
     // Manually create kernel to avoid replacing settings.
-    $kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'testing');
+    $classloader = require __DIR__ . '/../../../../../vendor/autoload.php';
+    $kernel = DrupalKernel::createFromRequest($request, $classloader, 'testing');
     $this->settingsSet('hash_salt', $this->databasePrefix);
     if (isset($modules_enabled)) {
       $kernel->updateModules($modules_enabled);
diff --git a/core/modules/system/src/Tests/System/IgnoreReplicaSubscriberTest.php b/core/modules/system/src/Tests/System/IgnoreReplicaSubscriberTest.php
index 49d11ec..0da6606 100644
--- a/core/modules/system/src/Tests/System/IgnoreReplicaSubscriberTest.php
+++ b/core/modules/system/src/Tests/System/IgnoreReplicaSubscriberTest.php
@@ -32,7 +32,8 @@ function testSystemInitIgnoresSecondaries() {
     Database::addConnectionInfo('default', 'replica', $connection_info['default']);
 
     db_ignore_replica();
-    $kernel = new DrupalKernel('testing', drupal_classloader(), FALSE);
+    $classloader = require __DIR__ . '/../../../../../vendor/autoload.php';
+    $kernel = new DrupalKernel('testing', $classloader, FALSE);
     $event = new GetResponseEvent($kernel, Request::create('http://example.com'), HttpKernelInterface::MASTER_REQUEST);
     $subscriber = new ReplicaDatabaseIgnoreSubscriber();
     $subscriber->checkReplicaServer($event);
diff --git a/index.php b/index.php
index 78ee18c..63a86ad 100644
--- a/index.php
+++ b/index.php
@@ -11,6 +11,7 @@
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\Site\Settings;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\ClassLoader\ApcClassLoader;
 
 $autoloader = require_once __DIR__ . '/core/vendor/autoload.php';
 
@@ -18,6 +19,20 @@
 
   $request = Request::createFromGlobals();
   $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
+
+  // By default, use the ClassLoader which is best for development, as it does
+  // not break when code is moved on the file system. However, as it is slow,
+  // the APC class loader can be used in production. To use the APC class loader
+  // simply uncomment the lines below. Note that ApcClassLoader decorates
+  // ClassLoader and only provides the findFile() method, but none of the others.
+  // The actual registry is still in ClassLoader.
+
+  // require_once __DIR__ . '/core/vendor/symfony/class-loader/Symfony/Component/ClassLoader/ApcClassLoader.php';
+  // $apc_loader = new ApcClassLoader('drupal.' . Settings::getHashSalt(), $autoloader);
+  // $autoloader->unregister();
+  // $apc_loader->register();
+  // $kernel->setClassloader($apc_loader);
+
   $response = $kernel
     ->handlePageCache($request)
     ->handle($request)
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 017fe8a..bd565b6 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -369,21 +369,6 @@
 # $settings['omit_vary_cookie'] = TRUE;
 
 /**
- * Class Loader.
- *
- * By default, Drupal uses Composer's ClassLoader, which is best for
- * development, as it does not break when code is moved on the file
- * system. It is possible, however, to wrap the class loader with a
- * cached class loader solution for better performance, which is
- * recommended for production sites.
- *
- * Examples:
- *   $settings['class_loader'] = 'apc';
- *   $settings['class_loader'] = 'default';
- */
-# $settings['class_loader'] = 'apc';
-
-/**
  * Authorized file system operations:
  *
  * The Update Manager module included with Drupal provides a mechanism for
