Spring学习一

明白控制反转,依赖注入,面向切面编程。

控制反转(Inversion of Control)就是依赖注入(Dependency Injection)的另一个表达,意思是本来我们需要一个需要某个对象是 要什么new 什么,而控制反转是反过来先配置好资源。即资源的不同获取方式。  而面向切面编程与面向对象编程的不同在于,面向对象是把一个抽象对象包装,包装对象应该有的方法和属性。而面向切面是,我们包装的是一个事物,一个流程,比如日记记录,什么七七八八的。

 

 

环境搭建

下载好spring 包 这里我用4.0版,下载之后之后导入。

1 Bean的注入方式,Bean中如何注入另一个Bean。

package com.test;

public class Car {//其中一个Bean
   private String factory;
   private double price;
   private int year;
public String getFactory() {
    return factory;
}
public void setFactory(String factory) {
    this.factory = factory;
}
public double getPrice() {
    return price;
}
public void setPrice(double price) {
    this.price = price;
}
public int getYear() {
    return year;
}
public void setYear(int year) {
    this.year = year;
}
public String toString() {
    return "Car [factory=" + factory + ", price=" + price + ", year=" + year
            + "]";
}
public Car(String factory, double price, int year) {
    super();
    this.factory = factory;
    this.price = price;
    this.year = year;
}
public Car (){}//使用参数构造bean必须提供无参数构造模式,不然会报错。
public Car(String factory, double price) {
    super();
    this.factory = factory;
    this.price = price;
}
public Car(String factory, int year) {
    super();
    this.factory = factory;
    this.year = year;
}
   
}



package com.test;

public class Person {//bean中带bean
      private String name;
      private int age;
      private Car car;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    public Person() {
        
    }
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
    }
      
}


package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {//测试类
     public static void main(String[] args) {
         ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//在工程目录下读取bean的配置。
         Car car = (Car)context.getBean("car1");//根据bean配置的ID进行配置
         System.out.println(car);
     //  Car car = context.getBean(Car.class); //这是直接根据类的配置,缺点是当我们有两个同样的Car的时候,会不知道读取哪一出 导致出错。
       Car car2 = (Car)context.getBean("car2");
       System.out.println(car2);
       Car car3 = (Car)context.getBean("car3");
       System.out.println(car3);
       Car car4 = (Car)context.getBean("car4");
       System.out.println(car4);
       
       Person p1 = (Person)context.getBean("person1");
       System.out.println(p1);
       Person p2 = (Person)context.getBean("person2");
       System.out.println(p2);
         
       }
}
<?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-3.0.xsd">

   
   
 <bean id="car1" class="com.test.Car" >
 <property name = "factory" value="futor"/>
 <property name = "price" value="2000"/>
 <property name = "year" value="5"/>
 </bean>
 
 
 <bean id="car2" class="com.test.Car" >
 <constructor-arg value = "aodu"></constructor-arg>
 <constructor-arg value = "50000"></constructor-arg>
 <constructor-arg value = "4"></constructor-arg>
 </bean>
 
 
 
 <!-- 以下两个bean,需要指定参数类型,避免bean不知道你要加载的构造模式是哪个,因为参数类型构造不能重复,以及特殊字符比如<>如何写 -->
 <bean id="car3" class="com.test.Car" >
 <constructor-arg >
 <value><![CDATA[<>auto]]></value>
 </constructor-arg>
 <constructor-arg value = "50000" type="double"></constructor-arg>
 </bean>
 
 <bean id="car4" class="com.test.Car" >
 <constructor-arg value = "aodu" type="java.lang.String"></constructor-arg>
 <constructor-arg value = "5" type="int"></constructor-arg>
 </bean>
   
   
 <!-- 参数里面的Bean应用用ref字符,内部构造的bean外部不能使用 -->
 <bean id ="person1" class="com.test.Person">
 <property name="name" value="xiaozhi"></property>
 <property name="age" value ="21"></property>
 <property name="car" ref="car1"></property>
 </bean>  
 
 <bean id ="person2" class="com.test.Person">
 <property name="name" value="xiaozhi"></property>
 <property name="age" value ="21"></property>
 <property name="car">
 <bean class="com.test.Car">
 <constructor-arg value = "aotuo"></constructor-arg>
 <constructor-arg value = "80000"></constructor-arg>
 <constructor-arg value = "8"></constructor-arg>
 </bean>
 </property>
 </bean>  

</beans>

上面是一个文件名为Bean的xml配置文件

 

级联属性要赋值需要先有初始化。stuct2会自动创建然后赋值上。

集合属性赋值,list,导入util命名空间可以独立实例化。

map属性 用entry key和value-ref

以及properties  用props  配置prop 全都key

以及使用p 来进行赋值

代码区

package com.test;

import java.util.List;

public class NewPerson {
     private String name;
     private int age;
     private List<Car>cars;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public List<Car> getCars() {
        return cars;
    }
    public void setCars(List<Car> cars) {
        this.cars = cars;
    }
     public NewPerson(){}
    @Override
    public String toString() {
        return "NewPerson [name=" + name + ", age=" + age + ", cars=" + cars
                + "]";
    }
     
}


package com.test;

import java.util.Map;

public class OldPerson {
       private String name;
       private int age;
       private Map<String,Car> cars;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Map<String, Car> getCars() {
        return cars;
    }
    public void setCars(Map<String, Car> cars) {
        this.cars = cars;
    }
    public OldPerson(){}
    @Override
    public String toString() {
        return "OldPerson [name=" + name + ", age=" + age + ", cars=" + cars
                + "]";
    }
    
}



package com.test;

import java.util.Properties;

public class DataSource {
     private Properties properties;

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "DataSource [properties=" + properties + "]";
    }
     
}


测试代码
package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
     public static void main(String[] args) {
         ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//在工程目录下读取bean的配置。
         NewPerson np = (NewPerson) context.getBean("newperson1");
         System.out.println(np);
         NewPerson np2 = (NewPerson) context.getBean("newperson2");
         System.out.println(np2);
         OldPerson op=(OldPerson) context.getBean("oldperson1");
         System.out.println(op);
         DataSource ds=(DataSource) context.getBean("datasource1");
         System.out.println(ds);
         Person p =(Person) context.getBean("personp");//利用P标签来实例化
         System.out.println(p);
         Person p2 =(Person) context.getBean("personp2");//利用自动装配来实例化
         System.out.println(p2);         
       }
}

xm添加代码

<!-- 用 list表示list数组 -->
 <bean id="newperson1" class="com.test.NewPerson">
 <property name="name" value="小智"></property>
 <property name="age" value="45"></property>
 <property name="cars">
 <list>
 <ref bean="car1"/>
 <ref bean="car2"/>
 <ref bean="car3"/>
 </list>
 </property>
 </bean>

<!-- 可以用util:list来独立实例化,这样需要的bean都能用到 比如下面的newpersons -->
<util:list id="cars1">
<ref bean="car1"/>
<ref bean="car2"/>
<ref bean="car3"/>
</util:list>

<bean id="newperson2" class="com.test.NewPerson">
 <property name="name" value="小盛"></property>
 <property name="age" value="45"></property>
 <property name="cars" ref="cars1"></property>
 </bean>
 
 <!-- map的使用方式 -->
 <bean id="oldperson1" class="com.test.OldPerson">
 <property name="name" value="小红"></property>
 <property name="age" value="45"></property>
 <property name="cars">
 <map>
 <entry key="名字一" value-ref="car1"></entry>
 <entry key="名字二" value-ref="car2"></entry>
 <entry key="名字三" value-ref="car3"></entry>
 </map>
 </property>
 </bean>

<!-- 常见的集合类,可以用来存储用户密码等等 -->
<bean id="datasource1" class="com.test.DataSource">
<property name="properties">
<props>
<prop key="UserName">无名</prop>
<prop key="PassWord">1123456789</prop>
<prop key="DatabaseDriver">www.sql.driver.link</prop>
</props>
</property>
</bean>

<!-- 这是利用 p 标签来在bean中设置属性,记得开头填写标签 -->
<bean id="personp" class="com.test.Person" p:age="10" p:name="cool" p:car-ref="car1"></bean>

<!-- 自动装配byName 则在setter方法名字一样装配,byType则根据类型,但是必须唯一 -->
<!-- 缺点多 整合框架会用到 -->
<bean id="personp2" class="com.test.Person" p:age="10" p:name="cool" autowire="byName"></bean>

 

 

 

 

 

 

 Bean之间的关系

继承关系parent

继承的父类里面的信息可以被子类重写,autowire 不能继承,可以专门写一个abstract的类来当抽象类,但是abstract类不能被实例化

依赖关系depends-on

依赖于某物的意思,必须有某物才能这个实例,但是内容不一定要用某物

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
     public static void main(String[] args) {
         ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//在工程目录下读取bean的配置。
       
         
         Person p3 =(Person) context.getBean("pperson");//继承关系
         System.out.println(p3);
         
         Person p4 =(Person) context.getBean("persond");//依赖关系
         System.out.println(p4);
         
         
       }
}

bean文件添加

<!-- 继承关系,重写,autowire不能重写。但是abstract 设置为true就不能实例化 -->
<bean id="persons" class="com.test.Person" p:name="xiaoxiaozhi" p:age="88" abstract="true"></bean>
<bean id="pperson" parent="persons" name="小智"></bean>

<!-- 依赖关系 depends-on ,依赖于cardpend的意思,必须有cardpend才能这个实例,但是内容不一定要用cardpend -->
<bean id = "cardepend" class="com.test.Car" p:factory="hongjing" p:price="888" p:year="5"></bean>
<bean id="persond" parent="persons" depends-on="cardepend" p:car-ref="cardepend"></bean>

 

 

 

Bean的作用域

bean是默认单例模式 即Singleton 但是可以修改成原型模式,原型模式是prototype,单例模式是在获取容器IoC构造的时候就构造好,而原型模式是我们之后需要的时候才构造,以下代码测试

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
     public static void main(String[] args) {
         ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");//在工程目录下读取bean的配置。
       
     
         Car car1= (Car) context.getBean("carsingle");
         Car car2= (Car) context.getBean("carsingle");
         Car car3= (Car) context.getBean("carproto");
         Car car4= (Car) context.getBean("carproto");
         System.out.println(car1==car2); 
         System.out.println(car3==car4); 
         //这段代码将会输出 true  false ,原因是在默认的单例模式下,car1和car2都是单例的引用,而在原型模式下
         //car3和car4是相当于需要的时候才创建,如果给car构造函数一个简单输出,会发现,在 ApplicationContext
         //装配好的时候就已经构造好单例模式,而原型模式是在创建好的时候才构造好。
       
       }
}

添加的bean

<!--默认是singleton,可以改成原型。-->
<bean id="carsingle" class="com.test.Car" p:factory="audi" p:price="5000" p:year="5" scope="singleton"></bean>
<bean id="carproto" class="com.test.Car" p:factory="audi" p:price="5000" p:year="5" scope="prototype"></bean>

 

 

 

PropertyPlaceholderConfigurer 是 BeanFactory 后置处理器的实现,也是 BeanFactoryPostProcessor 接口的一个实现。允许将上下文(配置文件)中的属性值放在另一个单独的标准 JavaProperties 文件中去。在 XML 文件中用类似 EL 表达式的 ${key} 替换指定的 properties 文件中的值。这样的话,以后更改参数时,我们直接替换 properties 文件中的值就可以了。

一些关键参数的设置就可以放在xxx.properties 里面,因为bean很多,可以很便捷。

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
     public static void main(String[] args) {
         ApplicationContext context = new       ClassPathXmlApplicationContext("Beans.xml");//在工程目录下读取bean的配置。
     Database db = (Database) context.getBean("database");
         System.out.println(db.getName());
         //成功输出root
       }
}


package com.test;

public class Database {//假设这是我们要配置的database
    private String name;
    private String password;
    private String url;
    private String driver;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getDriver() {
        return driver;
    }
    public void setDriver(String driver) {
        this.driver = driver;
    }
    
}

bean添加

<!--使用Beanfactory的后置处理器,就需要添加对应的标签 context 后面的value属性用"${xx}"  配置文件的名字-->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="database" class="com.test.Database">
<property name="name" value="${name}"></property>
<property name="password" value="${password}"></property>
<property name="url" value="${url}"></property>
<property name="driver" value="${driver}"></property>

对应的 db.properties文件是

name=root
password=123456
url=jdbc
driver=jdbc.driver

 

转载于:https://www.cnblogs.com/s1127736971/p/7503133.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值