Spring笔记

Posted chn.tiancx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring笔记相关的知识,希望对你有一定的参考价值。


说明下【本文是在网上听课做的笔记,代码是自己敲的,有些文字是复制的老师发的】

Spring

Spring框架介绍

Spring是一个轻量级的IoC和AOP的框架

IoC

控制反转

AOP

面向切面编程

Spring的功能

优点:
1)方便解耦,简化开发
Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给 Spring 管理。
2)方便集成各种优秀框架
Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如 Struts2、Hibernate、MyBatis
等)的直接支持。
3)降低 Java EE API 的使用难度
Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装,使这些
API 应用的难度大大降低。
4)方便程序的测试
Spring 支持 JUnit4,可以通过注解方便地测试 Spring 程序。
5)AOP 编程的支持
Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能。
6)声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无须手动编程。

接口和Spring 是完美搭配

以前

public interface UserDAO{
    void save();
}
public class UserDAOImpl implements UserDAO{
    public void save(){
        ....
    }
}
public class UserServiceImpl implements UserService{
    private UserDAO userDAO = new UserDAOImpl();
    public void reg(){
        userDAO.save();
    }
}
----------------------------------------------------
     
public class UserDAOJDBCImpl implements UserDAO{
	public void save(){
		....
	}
}

public class UserServiceImpl implements UserService{
    private UserDAO userDAO;
    public void reg(){
        userDAO.save();
        ....
    }
}

我们在UserServiceImpl中不再实例化DAO对象
从Spring容器中获得   

搭建Spring环境

1、添加依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.3.18.RELEASE</version>  
</dependency>

2、编写bean

package cn.cqie.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String uname;
    private String upwd;

}

3、编写配置文件

先将模板在idea中生成

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">
    <!--
        User user = new User();
        <bean>  声明实例化对象的信息
        id  对象的名称
        class 对象的类型
    -->
    <bean id="user" class="cn.cqie.pojo.User"></bean>
</beans>

4、测试获取user对象

package cn.cqie.test;

import cn.cqie.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppTest {
    @Test
    public void test(){
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("app.xml");
        User user = (User) applicationContext.getBean("user");
        System.out.println("AppTest.test"+user);
        user.setUname("yx");
        user.setUpwd("123");
        System.out.println(user);
    }
}

IOC容器介绍

BeanFactory

​ 在没有获取容器中实例时,不实例化对应的对象

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("app.xml"));
BeanFactory beanFactory1 = new XmlBeanFactory(new FileSystemResource("d:/app.xml"));

ApplicationContext

ApplicationContext applicationContext2 = new FileSystemXmlApplicationContext("d:/app.xml");
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
ApplicationContext applicationContext3 = new AnnotationConfigApplicationContext(JavaConfig.class);
User user = (User) applicationContext3.getBean("user");
System.out.println("AppTest.test"+user);
user.setUname("yx");
user.setUpwd("123");
System.out.println(user);

容器生成时,就会实例化配置文件中声明的对象

ApplicationContext从BeanFactory派生出来的

ApplicationContext增加了以下功能

  1. 国际化(MessageSource)

  2. 访问资源,如URL和文件(ResourceLoader)

  3. 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层

  4. 消息发送、响应机制(ApplicationEventPublisher)

  5. AOP(拦截器)

获取实例的简单的底层原理

package cn.cqie.util;

import cn.cqie.pojo.User;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MyClassPathXmlApplicationContext {
    Map<String,Object> container = new HashMap<>();
    public MyClassPathXmlApplicationContext(String resource){

        //获得resource对应的文件路径 或者 输入流
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(new File(resource));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //使用xml 解析技术(dom4j)读取xml文件的信息
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(inputStream);
            //读出标签<bean>、属性(id 、 class) 及值 (user 、 cn.cqie.pojo.User)
            Element rootElement = document.getRootElement();
            List<Element> elements = rootElement.elements();
            for (Element element:elements){
                System.out.println(element.getName());
                List<Attribute> attributes = element.attributes();
                String id = "";
                String clazz = "";
                for (Attribute attribute:attributes){
                    if(attribute.getName().equals("id")){
                        id = attribute.getValue();
                        System.out.println("id :"+id);
                    }else{
                        if(attribute.getName().equals("class")){
                            clazz = attribute.getValue();
                            System.out.println("clazz :"+ clazz);
                        }
                    }
                }
                //使用反射生成实例
                Class<?> aClass = Class.forName(clazz);
                Object obj = aClass.newInstance();
                
                //使用Map存储id和对应的实例
                container.put(id,obj);
            }

        } catch (DocumentException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }

    }
    public Object getBean(String id){
        return container.get(id);
    }

    public static void main(String[] args) {
        MyClassPathXmlApplicationContext context = new MyClassPathXmlApplicationContext("f:/app2.xml");
        User user = (User) context.getBean("user");
        user.setUname("tcx");
        System.out.println("user :"+user);
    }
}

Bean的概念

Spring中Bean就是一个类的实例

<bean id="" class="" />

Bean的生成方式有三种:

1、构造器生成

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<!--    通过构造器生成
		cn.cqie.pojo.User 必须有为空的构造器
-->
    <bean id="user" class="cn.cqie.pojo.User"/>
</beans>
    @Test
    public void testConstructor(){
        System.out.println(66);
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app2.xml");
        User user = (User) applicationContext.getBean("user");
        user.setUname("constructor  ");
        System.out.println(user);
    }

2、静态工厂

//UserStaticFactor.java
package cn.cqie.util;

import cn.cqie.pojo.User;

public class UserStaticFactor {
    public static User getUser(){
        return new User();
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<!--        通过静态工厂生成
			User user = UserStaticFactor.getUser();
-->
    <bean id="user2" class="cn.cqie.util.UserStaticFactor" factory-method="getUser"/>

</beans>
    @Test
    public void testStaticFactor(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app2.xml");
        User user2 = (User) applicationContext.getBean("user2");
        user2.setUname("static factory");
        System.out.println(user2);
    }

3、实例工厂

//	UserInstanceFactor.java
package cn.cqie.util;

import cn.cqie.pojo.User;

public class UserInstanceFactor {
    public User getUser(){
        return new User();
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<!--    实例化工厂构造
	UserInstanceFactor userInstanceFactor = new UserInstanceFactor();
    User user = userInstanceFactor.getUser();
-->
    <bean id="userInstanceFactor" class="cn.cqie.util.UserInstanceFactor" />
    <bean id="user3" factory-bean="userInstanceFactor" factory-method="getUser"/>
</beans>
    @Test
    public void testInstanceFactor(){
       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app2.xml");
        User user3 = (User) applicationContext.getBean("user3");
        user3.setUname("Instance factor ");
    }

Bean的作用域范围

scope有如下五个取值:

singleton:单例的(默认的),使用singleton定义的Bean是单例的,每次调用getBean都是调用的同一个对象。只要IoC容器一创建就会创建Bean的实例。
prototype:多例的,每次通过Spring IoC容器获取prototype定义的Bean时,容器都将创建一个新的Bean实例。创建时不会实例该Bean,只有调用getBean方法时,才会实例化。
request:作用于web的请求范围,在每一次HTTP请求时,容器会返回Bean的同一个实例,对不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前HTTP Request内有效。
session:作用于web的会话范围,在一次HTTP Session中,容器会返回该Bean的同一个实例,对不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前HTTP Session内有效。
global-session:作用于集群环境的会话范围(全局会话范围),在一个全局的HTTP Session中,容器返回Bean的同一个实例。当不是集群环境时,它就是session。

<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<!--    通过构造器生成-->
    <bean id="user" class="cn.cqie.pojo.User" scope="prototype"/>

</beans>
    @Test
    public void testScope(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("app3.xml");
        User user = (User) applicationContext.getBean("user");
        User user2 = (User) applicationContext.getBean("user");
        System.out.println(user==user2);
    }

依赖注入概述

dao层和service层 impl代码

package cn.cqie.dao.impl;

import cn.cqie.dao.UserDAO;

public class UserDAOImpl implements UserDAO 以上是关于Spring笔记的主要内容,如果未能解决你的问题,请参考以下文章

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

Spring boot:thymeleaf 没有正确渲染片段

What's the difference between @Component, @Repository & @Service annotations in Spring?(代码片段

spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段

Spring Rest 文档。片段生成时 UTF-8 中间字节无效 [重复]

解决spring-boot启动中碰到的问题:Cannot determine embedded database driver class for database type NONE(转)(代码片段