Spring基础知识小结

Posted schcode

tags:

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

Spring学习笔记
第一章 初识Spring
        Spring是轻量级的JAVA EE框架。Spring以IOC/DI、AOP为核心思想。其中,IOC是指控制反转或者反向
     控制,AOP是指切面编程。在Spring框架中,我们通过配置来创建类的对象,由Spring在运行阶段实例
	 化,组装对象,这叫控制反转;在执行一段代码之前或者之后或者同时,执行另一代段码,使程序更加
	 灵活,扩展性更好,这叫切面编程。
	    控制反转
		既然有反转,那么自然会有与之对应的"正转"。例如class A中有一个依赖类class B,即在class A中
		需要调用class B。
		public class A{
		   public void add(){
		      B b = new B();
		   }
		}
		在这里,我们手动new了class B。这是常规的,也就叫"正转"。那么"反转"就是将类交给Spring管理,
		当需要的时候,spring会自动创建一个类,这就是反转。
		例如:
		
		教师类:
		public class Techer {
	        private String name;
	        public void teach(){
		        System.out.println("我是人名教师!");
	        }
        }
		
		applicationContext.xml中:
		<bean id="techer" class="com.xt.beans.Techer"></bean>  
		
		测试类:
		public static void main(String[] args) {
		    String[] paths = new String[]{"spring/applicationContext.xml"};
		    BeanFactory bf = new ClassPathXmlApplicationContext(paths);
		    Techer techer = (Techer) bf.getBean("techer");
		    techer.teach();
	    }
		
		很显然,在测试类中,我们并没有手动new Techer(),而是从Bean工厂中取的。这就是控制反转。
	
第二章 Spring的三种注入方式以及自动注入
	  在第一章说道,使用Spring来管理类。让Spring来创建类的对象,既然如此,那自然要对类中的属性
	进行赋值。在Spring中,为类放入属性赋值有三种方式:设值注入、构造注入、接口注入。
	  1.设值注入
	      设值注入其实就是通过类中的setter()方法对属性进行赋值。
		  例如:
		  
		学生类
		Student.class:
		package com.xt.beans;

        public class Student {

	      private Integer id;
	      private String stuName;
	      private Integer age;
	      private String address;
	      
	      public Student(Integer id, String stuName, Integer age, String address) {
		    super();
		    this.id = id;
		    this.stuName = stuName;
		    this.age = age;
		    this.address = address;
	      }
	      public Student() {
		    super(); 
	      }
		  
		  setter()/getter()......
	
	      public void game(){
		    System.out.println("我叫"+this.stuName+",我今年"+this.age+"岁了。我家住在"+this.address);
	      }
        }
		
		applicationContext.xml中:
		<bean id="student" class="com.xt.beans.Student">
		  <!--设值注入-->
		  <property name="stuName" value="张三"></property>
		  <property name="age" value="22"></property>
		  <property name="age" value="24"></property>
          <property name="address" value="湖北省十堰市"></property>
		</bean>
		
		测试类:
		public static void main(String[] args) {
		    String paths[] = new String[]{"spring/applicationContext.xml"};
		    BeanFactory bf = new ClassPathXmlApplicationContext(paths);
		    Student student1 = (Student) bf.getBean("student");
		    Student student2 = (Student) bf.getBean("student");
		    System.out.println(student1==student2);
		    student1.game();
		    student2.game();
	    }
		
		运行结果:
		true
        我叫张三,我今年24岁了。我家住在湖北省十堰市
        我叫张三,我今年24岁了。我家住在湖北省十堰市
		
		解析:
		(1).在applicationContext.xml中,我们通过<property>标签为Student类中的属性进行赋值,这就是
		    设值注入。
		(2).从运行结果来看,spring默认为单态模式。在测试类中,我们可以看出,student1和student2是同
		    一个对象,这就充分说明Spring默认为单例模式。那么自然而然就有多态模式,如何让其变为多态模式?
			在<bean>中有一个属性:scope。
			scoped的取值有:
			default:默认单例模式
			prototype:多态模式
			session:在Spring创建对象后,会将对象放入session中
		
		(3).将模式变为多态模式:
		    <bean id="student" scope="prototype" class="com.xt.beans.Student">
		         ........
		    </bean>
		
		运行结果:
		false   <---------------
        我叫张三,我今年24岁了。我家住在湖北省十堰市
        我叫张三,我今年24岁了。我家住在湖北省十堰市
	2.构造注入(标签:<constructor-arg>)
	    顾名思义,通过类的构造方法对属性进行赋值。所以,类中要有有参构造方法。
		例如:
		学生类Student.class
		    同上.......
			
		applicationContext.xml中:
		<bean id="student" class="com.xt.beans.Student">
             <constructor-arg name="id" value="1"></constructor-arg>
             <constructor-arg name="stuName" value="张三"></constructor-arg>
             <constructor-arg name="age" value="23"></constructor-arg>
             <constructor-arg name="address" value="上海市宝山区"></constructor-arg>
        </bean>
	3.接口注入
	   当一个类A中需要另一个类B的方法来实现某些功能的时候,我们说A依赖于B。在这种情况下,我们
	   通常定义个接口IC,并让类B实现IC。
	   例如:
	   孩子类Child.class:
	   public class Child {
            private IParents parents;
			
			setter()/getter()......
			
			public Child(IParents parents){
			   this.parents = parents;
			}
	   }
	   接口:
	   public interface IParents {

	       public void print() throws Exception;
       }
	   
	   妈妈类:
	   public class Mother implements IParents{

	      public void print(){
		      System.out.println("我是孩子妈妈.....");
	      }
       }
	   
	   爸爸类:
	   public class Father implements IParents {

	       public void print() throws Exception {
		      System.out.println("我是孩子爸爸......");
	       }

       }
	   
	   applicationContext.xml中:
	    <bean id="mother" class="com.xt.beans.Mother"></bean>
        <bean id="father" class="com.xt.beans.Father"></bean>
        <bean id="child" class="com.xt.beans.Child">
          <constructor-arg name="parents" ref="father"></constructor-arg>
        </bean>
	4.自动注入(byName/byType)
	   在之前的学习过程中,我们都是显示注入,即ref="".其实在Spring中,还为我们提供了自动注入方式。
	   有两种:byType、byName.
	   (1).byType 根据类型注入
	       在Child中,需要一个接口IParents。该接口下有两个实现类,分别是:Mother / Father 。
		   那么Mother / Father 都属于IParents类型。
		   所以,在注入的时候,我们不需要再通过ref="mother"或者ref="father"来显示输入。而可以通过
		   <bean autowire="byType"></bean>来根据类型注入。
		   代码:
		   applicationContext.xml中:
		   <!--<bean id="mother" class="com.xt.beans.Mother"></bean>-->
           <bean id="father" class="com.xt.beans.Father"></bean>
           <bean id="child" class="com.xt.beans.Child" autowire="byType"></bean>
		   
		   运行结果:
		   我是孩子爸爸......
		   
		   注:
		     在上面的代码中,我们可以看出将id="father"注入到了Child 中。在使用byType自动注入的
			 时候,如果有两个及两个以上都属于同一种类型,即:多个类实现了同一个接口时,使用byType
			 会报错!因为不知道具体要注入哪一个.
	    (2).byName 通过名称自动注入
		   在Child中,需要一个接口IParents parents。该接口下有两个实现类,分别是:Mother / Father 。
		   如果在applicationContext.xml中,有bean的id与parents相同,通过autowire="byName"就会自动注入。
		   代码:
		   <bean id="mother" class="com.xt.beans.Mother"></bean>
           <bean id="parents" class="com.xt.beans.Father"></bean>
		   <bean id="child" class="com.xt.beans.Child" autowire="byName"></bean>
		   
		   运行结果:
		   我是孩子的爸爸......
		   
第三章 切面编程AOP
        在开发过程中,我们经常会遇到这种情况:在调用一个方法之前,希望系统能自动调用另一个方法;或者是执行
	完一个方法后,希望系统能自动调用另一个方法;或者是同时调用。。。。。当然我们可以手动去
	调用,但是这不方便。在Spring中,,为我们提供了面向切面编程的一种编程方式,让我们不用手动调用,而是
	当方法执行完成后,系统自己完成方法的执行。
	    我们设想一个场景:
		某个大型商场刚刚开业,商品都打折,吸引顾客。小明听说后,也去了商场购物。当他刚进商场大门时,喇叭里
		说道:"欢迎光临!祝您购物愉快!"小明于是高高兴兴走了进去,买了一大堆打折商品区结账。此时喇叭里又说
		道:"您此次消费1000元!"小明结了账后,走出商场,此时喇叭又说道:"欢迎下次光临!"
		我们可以把以上场景抽象为:
		(1).小明购物对应Custom类中的方法buy()
		(2).喇叭播放"欢迎光临"对应的是SuperMarket类中的方法welcome()
		(3).喇叭播放"您此次消费1000元!"对应的是SuperMarket类中的方法shouldPay()
		(4).喇叭播放"欢迎下次光临!"对应的是SuperMarket类中的方法sayGoodBy()
		那么我们现在要做的就是,在执行buy()之前,执行welcome();在执行buy()之后,执行sayGoodBy();
		在执行buy()同时,执行shouldPay()。
		那如何用切面编程来完成呢?
	1.导入相应的jar包
	  spring-aop.jar、aspectjweaver.jar、aspectjrt.jar
	2.Custom类:
	  public class Custom {
	
	      private BigDecimal payMoney;
	
	

	      public BigDecimal getPayMoney() {
		      return payMoney;
	      }



	      public void setPayMoney(BigDecimal payMoney) {
		      this.payMoney = payMoney;
	      }



	      public void buy(){
		      System.out.println("我来购物啦!");
	      }
      }
	  
    (3).SuperMarket类:
	    public class SuperMarket {

	        public void welcome(){
		       System.out.println("欢迎光临!祝您购物愉快!");
	        }
	
	        public void shouldPay(JoinPoint point){
		      Custom customer = (Custom) point.getTarget();
		      System.out.println("您需要支付"+customer.getPayMoney()+"元。");
	        }
	
	        public void sayGoodBy(){
		      System.out.println("欢迎下次光临!");
	        }
        }
	(4).applicationContext中的:
	    <bean id="custom" class="com.xt.superMarket.Custom">
           <property name="payMoney" value="1000"></property>
        </bean>
        <bean id="market" class="com.xt.superMarket.SuperMarket"></bean>
        <!-- aop配置 -->
        <aop:config>
            <!-- 配置切面 -->
            <aop:aspect id="supermarket" ref="market">
                <!-- 配置切点 -->
                <aop:pointcut id="pointcut" expression="execution(* com.xt.superMarket.Custom.*(..))"></aop:pointcut>
                <!-- 配置通知方式 -->
                <!-- 前置通知 -->
                <aop:before method="welcome" pointcut-ref="pointcut"></aop:before>
                <!-- 环绕通知 -->
                <aop:around method="shouldPay" pointcut-ref="pointcut"></aop:around>
                <!-- 后置通知 -->
                <aop:after method="sayGoodBy" pointcut-ref="pointcut"></aop:after>
            </aop:aspect>
        </aop:config>
		解析:
		(1).<aop:pointcut id="pointcut" expression="execution(* com.xt.superMarket.Custom.*(..))"></aop:pointcut>
		    配置切点
			第一个*代表:任意返回类型,这里是void;
			第二个*是任意方法,这里是buy();
			(..)表示任意个参数

	
		   

	
		


		
	   
		

  

以上是关于Spring基础知识小结的主要内容,如果未能解决你的问题,请参考以下文章

180531-Spring中JavaConfig知识小结

spring-知识小结之注解为属性赋值

Spring知识点小结

Spring框架--小结

JAVA枚举小结

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