栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring学习笔记

Spring 一、简介
  • 理念:使现有的技术更加容易使用,本身是一个大杂烩,整合现有的技术框架
  • SSH:Struct2 + Spring + Hibernate
  • SSM :SpringMvc + Spring + Mybatis

	org.springframework
    spring-webmvc
    5.2.0.RELEASE


	org.springframework
    spring-jdbc
    5.2.0.RELEASE

优点:
  • Spring是一个开源的免费的框架
  • 是一个轻量级,非入侵式的框架
  • 控制反转(IOC),面向切面编程(AOP)
  • 支持事务的处理,对框架整合的支持
二、组成

  • Spring Boot
    • 一个快速开发的脚手架
    • 基于Spring Boot可以快速的开发单个微服务
    • 约定大于配置
  • Spring Cloud
    • Spring Cloud是基于Spring Boot实现的
三、IOC理论推导
  1. UserDao 接口

    public interface UserDao{
    	void getUser();
    }
    
  2. UserDaoImpl 实现类

    public class UserDaoImpl implements UserDao{
        public void getUser(){
            System.out.println("默认获取用户数据");
        }
    }
    
  3. UserService 业务接口

    public interface UserService{
        void getUser();
    }
    
  4. UserServiceImpl 业务实现类

    public class UserServiceImpl implements UserService{
        
        private UserDao userDao = new UserDaoImpl();
        
        public void getUser(){
            userDao.getUser();
        }
    }
    

原本业务中,用户需求会影响代码,成本代价很大。

使用Set接口实现:

public class UserServiceImpl implements UserService{
    
    private UserDao userdao;

    //利用set进行动态实现值的注入!
    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }
    //根据多态,将UserDao的多个实现类,以最终使用时实例化的对象类型注入。
    //满足开闭原则。
    public void getUser(){
        userDao.getUser();
    }
}
IOC本质

控制反转IOC(Inversion of Control)是一种设计思想,DI(依赖注入)是实现IOC的一种方法。也有人认为DI只是IOC的另一种说话,没有IOC的程序中,我们使用面向对象编程,对象的创建与对象的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三发那个。

所谓控制反转就是:获得依赖对象的方式反转了

采用XML方法配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以直接的形式定义在实现类中,从而达到零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(Dependency Injection,DI)。

HelloSpring
  1. 配置XML文件——ApplicationContext.xml,这里简写为Beans.xml

    
        
        
        	
        
    
    
  2. 测试类

    public class MyTest{
        public static void main(String[] args){
            //获取Spring的上下文对象
            //这句话是写死的,都是这样的,里面可以传两个参数,通过配置文件读取
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Hello hello = (Hello) context.getBean("hello");
            System.out.println(hello.toSring());
            
        }
        
    }
    
  3. 实体类

    public class Hello{
        
        private String str;
        
        public Sring getStr(){
            return str;
        }
        //核心是调用set函数,来设置str的值实现new
        public void setStr(String str){
            this.str = str;
        }
        
        @Override
        public String toString(){
            return "Hello{" +
                "str=" + str +'}';
        }
    }
    
修改之前的代码

    
    
    
    	
        
    
     
     

public class MyTest{
    public static void main(Sting[] args){
        //获取ApplicationContext:拿到Spring的容器,参数可以输入多个xml,用","隔开
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //需要什么就get什么
        UserServiceImpl userServiceImpl = (UserServiceImpl)context.getBean("UserServiceImpl");
        
        userServiceImpl.getUser();
    }
}

//如果要改的话就只需要改用户文件就可以了
四、IOC创建的对象的方式 默认无参构造

	

有参构造方式

    
	
    	
    
    
	
    	
    
    
	
    	
    

五、Spring配置说明 5.1 别名


5.2 Bean的配置

	


    private String address;
    public String getAddress(){实现}
    public void serAddress(String address){
        this.address = address;
    }
}
  • 真实测试对象

    public class Student{
    	private String name;
    	private Address addresss;
    	private String[] books;
    	private List hobbies;
    	private Map card;
    	private Set games;
    	private String girlfriend;
    	private Properties info;
    }
    
  • beans.xml

    
    
        
        	
        
    	
        	
            
            
            
            
            
            
            	
                	红楼梦
                    西游记
                    水浒传
                    三国演义
                
            
             
            
            	
                	听歌
                    打球
                
            
            
            
            	
                	
                    
                
            
             
            
            	
                	LOL
                    COC
                    BOB
                
            
            
            
            	
            
            
            
            	
                	2020214586
                    root
                
            
        
    
    
    
        public static void main(String[] args){
            ApplicationContet context = new ClassPathXmlApplicationContext("beans.xml");
            Student student = (Student)context.getBean("student");
            System.out.println(student.toString());
        }
    }
    
  • 6.3 拓展方式注入
    1. p命名空间注入,可以直接注入属性

      1. 在beans官方配置中加入P命名空间配置

      2. 
        
    2. c命名空间注入

      1. 在beans官方配置中加入c命名空间配置

      2. 
        

    注意点:不能直接使用,要去导入xml约束

    6.4 bean的作用域

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RzIJH2E1-1637831528658)(C:Users86135AppDataRoamingTyporatypora-user-imagesimage-20211124190039417.png)]

    1. 单例模式(Spring默认机制)

      
      
      
    2. 原型模式

      
      
      
    3. 其余的request、session、application、websocket,只有在web开发中能够使用。

    七、Bean的自动装配
    • 自动装配是Spring满足Bean依赖的一种方式
    • Spring会在上下文中自动寻找,并自动给bean装配属性

    Spring有三种装配的方式

    1. 在xml显式装配
    2. 在java中显式装配
    3. 隐式的自动装配
    7.1 byName自动装配
    
    
    
    
    	
     
    
    
    7.2 byType自动装配
    
    
    
    
    	
     
    
    

    小结:

    • byName的时候,需要保证所有bean 的id唯一,并且bean需要和自动注入的属性的set方法的值一致
    • bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
    7.3 使用注解实现自动装配

    jdk1.5支持的注解,Spring2.5开始支持注解

    要使用注解须知:

    1. 导入约束:context约束
    2. 配置注解的支持:context:annotation-config/
    
        
        
        
        
        
    
    

    实现类:

    public class People{
    	@Autowired //写注解
    	private Dog dog;
        @Autowired //写注解
    	private Cat cat;
        @Autowired //写注解
        private String name;
    }
    
    @Autowired 一般用这个就够了

    在使用属性上使用即可,也可以在set方式上使用。

    使用Autowired可以不编写Set方法了,前提是这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byName。

    //加上@Nullable之后,即使为空也不报错
    public People(@Nullable String name){
    	this.name = name;
    }
    
    //如果显式定义了Autowired的required属性为false,即使为空也不会报错
    @Autowired(required = false)
    private Cat cat;
    

    如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value=“xxx”)去配合@Autowired的使用,指定注解的唯一配置注入。

    还可以使用@Resource来指定byName
    //如果在xml中有多个对象,也可以通过@Resource的name属性来对应相应的属性
    @Resource(name="cat2")
    private Cat cat;
    

    小结:

    @Resource和@Autowired的区别:

    • 都是用来自动装配的,都可以放在属性字段上。
    • @Autowired通过bytype的方式实现,而且必须要求这个对象存在(或者手动设置可以不存在)【常用】
    • @Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现。
    • 执行顺序不同:@Autowired先类型后名字,@Resource先名字后类型
    八、使用注解开发

    在Spring4之后,在使用注解的时候,必须要导入一个aop的包。

    使用注解需要增加注解的约束,获得注解的支持。

    1. bean

      
      
      	
      	
          
      
      
      //等价于 
      @Component
      public class User{
          public String name = "TuNan";
      }
      
      public class MyTest{
          public static void main(String[] args){
              ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
              User user = (User)context.getBean("user"); //bean默认就是类型的小写
              System.out.println(user.name);
          }
      }
      
    2. 属性如何注入

      //等价于 
      @Component
      public class User{
          //复杂的还是要在配置文件里面写,比如数组等。
          //相当于
          @Value("TuNan")
          public String name;
      }
      
    3. 衍生的注解

      @Component有几个衍生注解,在web开发中,会按照mvc三层架构分层。

      • dao 【@Repository】
      • service 【@Service】
      • controller 【@Controller】

      这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean。

    4. 自动装配

      • Autowired : 自动装配通过类型,名字。

        如果Autowired不能唯一自动装配到属性,则需要通过@Qualifier(value=“xxx”)。

      • @Nullable : 字段标记了这个注解,说明这个字段可以为null。

      • @Resource :自动装配通过名字,类型。

    5. 作用域

      @Scope

      • 单例模式 @Scope(“singleton”)
      • 原型模式 @Scope(“prototype”)
    6. 小结

      xml与注解:

      • xml更加万能,适用于任何场合,维护简单方便
      • 注解不是自己类使用不了,维护相对复杂

      xml与注解最佳实践:

      • xml用来管理bean
      • 注解只负责完成属性的注入
      • 在使用过程中,只需要注意一个问题,必须让注解生效,就需要开启注解的支持
    
    
    	
    	
        
    
    
    九、使用JavaConfig实现配置

    完全不适用xml配置,全权交给Java来做,JavaConfig是Spring的一个子项目,在Spring4之后,九成为了一个核心功能。

    //这个注解就是说这个类被Spring接管了,注册到了容器中
    @Component
    public class User{
        private String name;
        
        public String getName(){
            return name;
        }
        
        @Value("TuNan")//属性值注入
        public void setName(String name){
            this.name = name;
        }
    }
    
    // 这个也会被Spring容器托管,注册到容器中,因为他本来就是一个@Component
    // @Configuration代表这是一个配置类,就类似于之前的beans.xml
    @Configuration
    @ComponentScan("com.tunan.pojo")
    @import(TuNanconfig2.class)
    public class TuNanConfig{
        //注册一个bean,相当于bean标签
        //方法名,对应bean标签的id属性
        //方法返回值,对应bean标签class属性
        @Bean
        public User user(){
            return new User();   //就是返回要注入到bean的对象
        }
    }
    
    public class MyTest{
        public static void main(String args[]){
            //如果完全使用配置类方法去做,只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象加载。
            ApplicationContext context = new AnnotationConfigApplicationContext(TuNanConfig.class);
            User user = (User)context.getBean("user");
            System.out.println(getUser.getName());
        }
    }
    

    这种纯Java的配置方式,在SpringBoot中随处可见。

    十、代理模式

    代理模式是SpringAOP的底层。【SpringAOP 和 SpringMVC】

    代理模式分类

    • 静态代理
    • 动态代理
    10.1 静态代理
    • 角色分析:

      • 抽象角色:一般会使用接口或者抽象类来解决
      • 真实角色:被代理的角色
      • 代理角色:代理真实角色,代理真实角色后,一般做一些附属操作
      • 客户:访问代理对象的人
    • 优势:

      • 可以使真实角色的操作更加纯粹,不用去关注公共业务
      • 公共业务交给代理角色,实现了业务的分工
      • 公共业务发生拓展的时候,方便集中管理
    • 缺点:

      • 一个真实角色产生一个代理角色,代码量翻倍
    • 代码步骤:

      1. 接口
      2. 真实角色
      3. 代理角色
      4. 客户端访问代理角色

    10.2 动态代理
    • 动态代理和静态代理所具有的角色一样
    • 动态代理的代理类是动态生成的,不是直接写好的
    • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
      • 基于接口—JDK动态代理
      • 基于类:cglib
      • Java字节码实现:javassist

    需要了解两个类:Proxy(代理),InvocationHandler(调用处理程序,接口)

    public class ProxyInvocationHandler implements InvocationHandler {
        
        //被代理的接口
        private Rent rent;
        
        public void setRent(Rent rent){
            this.rent = rent;
        }
        
        //生成得到代理类
        public Object getProxy(){
            return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
        }
        
        //处理代理实例,并返回结果
        public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
           //动态代理的本质,就是使用反射机制实现。
            seeHouse();
            Object result = method.invoke(rent,args);
            fare();
            return result;
        }
    }
    
    public class Client{
        public static void main(String[] args[]){
            //真实角色
            Host host = new Host();
            
            //代理角色
            ProxyInvocationHandler pih = new ProxyInvocationHandler();
            
            //通过调用程序处理角色来处理我们要调用的接口对象
            pih.setRent(host);//设置要代理的对象
            Rent proxy = (Rent)pih.getProxy(); //Proxy就是动态生成的。
            proxy.rent();
        }
    }
    
    十一、AOP 11.1 简介

    AOP(Aspect Oriented Programming)面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合降低,提可复用率。

    11.2 AOP在Spring中的作用

    提供声明式事务,允许用户自定义切面

    • 横切关注点:跨越应用程序多个模块的方法或功能。与业务逻辑无关的,但是就是需要关注的部分,如日志,缓存等
    • 切面(Aspect) : 横切关注点被模块化的特殊对象。一个类
    • 通知(Advice) : 切面必须要完成的工作。类中的一个方法
    • 目标(Target) : 被通知的对象。
    • 代理(Proxy) : 向目标对象应用通知之后创建的对象。
    • 切入点(PointCut) : 切面通知执行的"地点"的定义
    • 连接点(JointPoint) : 与切入点匹配的执行点。

    11.3 使用Spring AOP需要导包
    
        
            org.aspectj
            aspectjweaver
            1.9.4
        
    
    
    11.4 方式一:使用Spring的API接口
    public class Log implements MethodBeforeAdvice{
        //method : 要执行目标对象的方法
        //args : 参数
        //target : 目标参数
        public void before(Method method,Object[] args,Object target) throws Throwable{
            System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
        }
    }
    
    public class AfterLog implements MethodReturningAdvice{
        //returnValue:返回值
        //method : 要执行目标对象的方法
        //args : 参数
        //target : 目标参数
        public void before(Object returnValue,Method method,Object[] args,Object target) throws Throwable{
            System.out.println("执行力"+method.getName()+"方法,返回结果为"+returnValue);
        }
    }
    
    
    
        
    	
        
        
        
        
        	
            
            
            
            
            
        
        
    
    
    public class Mytest{
        public static void main(String args[]){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            //动态代理代理的是接口,不是实现类
            UserService userServic = (UserService)context.getBean("userService");
            
            userService.add();
        }
    }
    
    11.5 方式二 自定义切面类(包含各种切入点函数)
    
    
        
    	
        
        
        
        
        
        	
            
                
            	
                
                
            
        
    
    
    11.6 使用注解实现AOP
    @Aspect	//标注这个类是一个切面
    public class AnnotationPointCut{
        @Before("excution(* com.tunan.service.UserServiceImpl.*(..))")
        pulic void before(){
            System.out,println("方法执行前=====");
        }
        @After("excution(* com.tunan.service.UserServiceImpl.*(..))")
        pulic void before(){
            System.out,println("方法执行后=====");
        }
        @Around("excution(* com.tunan.service.UserServiceImpl.*(..))")
        public void around(ProceedingJoinPoint jp) throws Throwable{
            System.out.println("环绕前");
            Signature signature = jp.getSignature(); //获得签名
            System.out.println("signature:" + signature);
            Object proceed = jp.proceed(); //执行方法
            System.out.println("环绕后");
        }
    }
    
    
    
    
    
    十二、整合Mybatis

    步骤:

    1. 导入jar包
      • junit
      • mybatis
      • mysql数据库
      • spring相关包
      • aop注入
      • mybatis-spring
    2. 编写配置文件
    3. 测试
    12.1 mybatis-spring

    配置spring-dao.xml

    
    
        
        
    	
        
        	
            
            
            
        
        
        
        
        	
            
            
            
        
        
        
        	
            
        
        
        
        
        
        	
        
    
    

    在Mybatis中的操作用sqlSession执行,在这里都用SqlSessionTemplate

    //接口实现类
    public class UserMapperImpl implements UserMapper{
        
        private SqlSessionTemplate sqlSession;
        
        public void setSqlSession(SqlSessionTemplate sqlSession){
            this.sqlSession = sqlSession;
        }
        public List selectUser(){
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.selectUser();
        }
    }
    
    

    applicationContext.xml

    
    
        
    	
        
        
        	
        
    
    

    UserMapper.xml

    
    
    	
    		
    	
    
    
    12.2 SqlSessionDaoSupport

    这是一个抽象的支持类,用来提供SqlSession,调用getSqlSession()方法会得到一个SqlSessionTemplate,之后可以用于执行SQL方法。

    //要继承SqlSessionDaoSupport类
    public class USerMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
        public List selectUser(){
            SqlSession sqlSession =  getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.selectUser();
        }
    }
    
    
    
        
        	
            
            
            
        
        
        
        
        	
            
            
            
        
        
        
        	
            
        
    	
        
        
        
    
    
    十三、声明式事务 13.1 事务
    • 把一组业务当作一个业务来做,要么都成功,要么都失败

    • 确保完整性和一致性

    • 事务的ACID原则:

      • 原子性
      • 一致性
      • 隔离性
        • 多个业务可能操作同一个资源,放置数据损坏
      • 持久性
        • 事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化写道存储器中
    • 用途

      防止一个方法中同时操作了增删改查多个操作的时候,前几个操作执行成功了,但是有操作执行失败,导致逻辑和数据混乱。

    13.2 spring中的事务管理
    • 声明式事务:AOP
    • 编程式事务:
    
    
        
        	
            
            
            
        
        
        
        
        	
            
            
            
        
        
        
        	
            
        
    	
        
        
        
        
        	
        
        
        
        
        
            
            
        	
            	
                
                
                
            
        
    
    
    转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/602983.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号