重溫Spring之IoC(二)



有點長 有點雜 加油 🦆 🦆


實例化Bean方法

構造方法

無參構造

  • xml
<?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="org.example.User">
        <property name="name" value="xixi"></property>
        <property name="gender" value="0"></property>
    </bean>
</beans>
  • java
public class User {
    private  String name;
    private  String gender;

    public User() {
        System.out.println("constructor User()");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}
  • text
    @Test
    public void Test() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = ac.getBean(User.class);
        System.out.println(user.toString());

    }
  • console
constructor User()
User{name='xixi', gender='0'}

有參構造

  • xml
<?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="user2" class="org.example.User">
        <constructor-arg name="name1" value="xixi"></constructor-arg>
        <constructor-arg name="gender1" value="0"></constructor-arg>
    </bean>
</beans>
  • java
package org.example;

public class User {
    private  String name;
    private  String gender;

    public User() {
        System.out.println("constructor User()");
    }

    public User(String name1, String gender1) {
        System.out.println("constructor User(String,String)");
        this.name = name1;
        this.gender = gender1;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

  • test
    @Test
    public void Test() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = ac.getBean(User.class);
        System.out.println(user.toString());

    }

console

constructor User(String,String)
User{name='xixi', gender='0'}

靜態工廠(靜態方法)

無參

  • xml
<bean id="user" class="org.example.UserBeanFactory" factory-method="getUserBean">
    <property name="gender" value="0"></property>
    <property name="name" value="xixi"></property>
 </bean>
  • java
public class UserBeanFactory {
    public static User getUserBean(){
        return new User();
    }
}
  • test
    @Test
    public void Test() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        //User bean = (User)ac.getBean("user");
        User bean = (User)ac.getBean(User.class);
        System.out.println(bean);
    }
  • console
constructor User()
User{name='xixi', gender='0'}

有參

  • xml
<bean id="user" class="org.example.UserBeanFactory" factory-method="getUserBean">
    <constructor-arg name="gender" value="0"></constructor-arg>
    <constructor-arg name="nm" value="xixi"></constructor-arg>
</bean>
  • java
    public static User getUserBean(String nm,String gender){
        System.out.println(" getUserBean(String nm,String gender)");
        User user =  new User();
        user.setGender(gender);
        user.setName(nm);
        return user;
    }
  • test
    @Test
    public void Test() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        User bean = (User)ac.getBean(User.class);
        System.out.println(bean);
    }
  • console
getUserBean(String nm,String gender)
constructor User()
User{name='xixi', gender='0'}

Calendar.getInstance(),System.getenv("JAVA_HOME")

實例工廠(非靜態方法)

無參

  • xml
<?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="userBeanFactory" class="org.example.UserBeanFactory">
    </bean>

    <!-- factory-bean:工廠對象, factory-method:工廠方法-->
    <bean id="userBean" factory-bean="userBeanFactory" factory-method="getUserBean">
        <property name="name" value="xixi"></property>
        <property name="gender" value="0"></property>
    </bean>
</beans>
  • java
public class UserBeanFactory {
    public  User getUserBean(){
        return new User();
    }
}
  • test
    @Test
    public void Test() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        User bean = (User) ac.getBean("userBean");

        User bean1 = (User) ac.getBean(User.class);
        System.out.println(bean.toString());
        System.out.println(bean1.equals(bean));
        System.out.println(bean1.toString());
    }
  • console
constructor User()
User{name='xixi', gender='0'}
true
User{name='xixi', gender='0'}

有參

  • xml
  <bean id="userBean" factory-bean="userBeanFactory" factory-method="getUserBean">
        <!--        <property name="name" value="xixi"></property>-->
        <!--        <property name="gender" value="0"></property>-->
        <constructor-arg name="nm" value="xixi"></constructor-arg>
        <constructor-arg name="gender" value="0"></constructor-arg>
  </bean>
  • java
public  User getUserBean(String nm,String gender){
        System.out.println(" getUserBean(String nm,String gender)");
        User user =  new User();
        user.setGender(gender);
        user.setName(nm);
        return user;
    }
  • test
    @Test
    public void Test() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        User bean = (User) ac.getBean("userBean");

        User bean1 = (User) ac.getBean(User.class);
        System.out.println(bean.toString());
        System.out.println(bean1.equals(bean));
        System.out.println(bean1.toString());
    }
  • console
getUserBean(String nm,String gender)
constructor User()
User{name='xixi', gender='0'}
true
User{name='xixi', gender='0'}

練習

練習1:java獲取時間

        Calendar calendar = Calendar.getInstance();
        Date date = calendar.getTime();


  • IoC容器獲取
    <bean id="calendar" class="java.util.Calendar" factory-method="getInstance"></bean>
    <bean id="date" factory-bean="calendar" factory-method="getTime" ></bean>
 Date bean = (Date) ac.getBean("date");

練習2:數據庫連接

  • java獲取鏈接
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/XI?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8","root","1234");
        PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM USER");


  • IoC獲取
   <bean class="java.lang.Class" factory-method="forName">
        <constructor-arg name="className" value="com.mysql.jdbc.Driver"></constructor-arg>
    </bean>

    <bean id="connection" class="java.sql.DriverManager" factory-method="getConnection">
        <constructor-arg name="url" value="jdbc:mysql://localhost:3306/XI?serverTimezone=UTC"></constructor-arg>
        <constructor-arg name="user" value="root"></constructor-arg>
        <constructor-arg name="password" value="1234"></constructor-arg>
    </bean>

    <bean id="preparedStatement" factory-bean="connection" factory-method="prepareStatement">
        <constructor-arg name="sql" value="SELECT * FROM USER"></constructor-arg>
    </bean>
 PreparedStatement ps =  (PreparedStatement)ac.getBean("preparedStatement");


實例化bean時機

ClassPathXmlApplicationContext

// 默認預先實例化
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
<!-- lazy-init="true" 懶實例化 
     lazy-init="false" 預先實例化 -->
<bean class="org.example.User" lazy-init="true"></bean>


BeanFactory

// 懶實例化 
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
<bean class="org.example.User" ></bean>


Bean作用域配置

  • scope
  • singleton 單例(單例中的全局屬性在多線程中不安全)
  • prototype 非單例
  • request 同一個請求中單例
  • session 同一個會話中單例


Bean繼承配置

  • 不同子類繼承同一個bean
    <bean id="common" abstract="true">
        <property name="name" value="XI"></property>
        <property name="gender" value="boy"></property>
    </bean>

    <bean id="bean1" class="org.example.Bean1" parent="common">
        <property name="tag" value="知行合一"></property>
    </bean>

    <bean id="bean2" class="org.example.Bean2" parent="common">
        <property name="score" value="100"></property>
    </bean>
  • 相同子類繼承同一個bean
    <bean id="common1" class="org.example.Bean1">
        <property name="name" value="XI"></property>
        <property name="gender" value="boy"></property>
    </bean>
    
    <bean id="bean3"  parent="common1">
        <property name="tag" value="知行合一"></property>
    </bean>


    <bean id="bean4"  parent="common1">
        <property name="tag" value="善於思考"></property>
    </bean>


自動裝配

(僅適用於一個bean引用其他bean)

  • autowire=byName/byType/constructor/no/default

constructor:先byName后byType

  • 並非所有類都交由Ioc容器進行管理


在一個自身不在IoC容器的bean中獲取IoC容器

  • 添加實現接口ApplicationContextAware的工具類
public class ApplicationContextHolder implements ApplicationContextAware {

    private static ApplicationContext ac;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println(applicationContext);
        ac = applicationContext;
    }
    
    public static Object getBean(String beanName){
        return ac.getBean(beanName);
    }
    
    public static <T> T getBean(Class<T> clazz){
        return ac.getBean(clazz);
    }
}
  • 到IoC容器中
    <bean id="user" class="org.example.User"></bean>
    <bean class="org.example.ApplicationContextHolder"></bean>
  • test
    @Test
    public void Test() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        System.out.println(ApplicationContextHolder.getBean("user"));

        System.out.println(ApplicationContextHolder.getBean(User.class));

    }


FactoryBean

  • bean類型
    1.普通Bean 返回bean本身的對象
    2.工廠Bean 返回任意類型
  • 實現FactoryBean接口,返回的bean類型是getObject()返回的類型

public class PreparedStatementFactoryBean implements FactoryBean<PreparedStatement> {
    /**
     * 生成實例的過程
     * @return
     * @throws Exception
     */
    @Override
    public PreparedStatement getObject() throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/XI?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8","root","1234");
        PreparedStatement ps = connection.prepareStatement("SELECT * FROM USER");
        return ps;
    }

    /**
     * 生成實例類型,此方法為兼容老版本的代碼
     * @return:實例類型
     */
    @Override
    public Class<?> getObjectType() {
        return PreparedStatement.class;
    }

    /**
     * 是否單例
     * true:單例,false:非單例
     * @return
     */
    @Override
    public boolean isSingleton() {
        return false;
    }
}
  • 放到IoC容器中
    <bean id="ps" class="org.example.PreparedStatementFactoryBean"></bean>
  • test
    @Test
    public void Test() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println(ac.getBean("ps"));
    }
  • console
com.mysql.cj.jdbc.ClientPreparedStatement: SELECT * FROM USER


Resource

基本用法

根據文件文職不同,來快速獲取文件資源

裝配

    <bean id="myResources" class="org.example.MyResources">
        <property name="resource" value="file:F:\itool\springframework\spring-ioc"></property>
        <!--<property name="resource" value="classpath:applicationContext.xml"></property>-->
    </bean>
  • test
    @Test
    public void Test() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        MyResources myResources = (MyResources)ac.getBean(MyResources.class);
        Resource resource = myResources.getResource();
        System.out.println(resource.getFilename());
    }


后置處理器

Bean后置處理器 BeanPostProcessor

  • 時機:初始化方法之前/之后
    代碼塊->實例化->數據裝配->初始化之前->初始化方法->初始化之后->就緒->使用->銷毀方法->容器銷毀
  • 使用:實現BeanPostProcessor接口,放置IoC容器
    

BeanFactory后置處理器 BeanFactoryPostProcessor

  • 時機:Bean創建之前
    BeanFactoryPostProcessor->代碼塊->實例化->數據裝配->初始化之前->初始化方法->初始化之后->就緒->使用->銷毀方法->容器銷毀
  • eg:在容器中注冊屬性編輯器
    (屬性編輯器:實現接口PropertyEditor或繼承PropertyEditorSupport)

練習PropertyEditorSupport

  • eg
<?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 class="org.example.User"></bean>

    <bean id="bean1" class="org.example.Bean1" init-method="toString">
        <property name="user" value="[xixi-boy]"></property>
        <property name="tag" value="春和景明"></property>
    </bean>


    <bean class="org.example.MyBeanFactoryProcessor"></bean>
    <bean class="org.example.MyBeanPostProcessor"></bean>
</beans>
public class UserEditor extends PropertyEditorSupport {

    @Override
    public String getAsText() {
        return super.getAsText();
    }

    /**
     * 將text轉化為User
     * @param text
     * @throws IllegalArgumentException
     */
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        Pattern pattern = Pattern.compile("\\[(.*)-(.*)\\]");
        Matcher matcher = pattern.matcher(text);
        if(matcher.matches()){
            User user = new User();
            user.setName(matcher.group(1));
            user.setGender(matcher.group(2));
            setValue(user);//賦值
        }
    }
}
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
        System.out.println("postProcessBeanFactory");
        factory.registerCustomEditor(User.class,UserEditor.class);

    }
public class Bean1 {
    private  User user;
    private String tag;

    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

}

改造練習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">
    <bean class="org.example.User"></bean>

    <bean id="bean1" class="org.example.Bean1" init-method="toString">
        <property name="user" value="[xixi-boy]"></property>
        <property name="tag" value="春和景明"></property>
    </bean>


    <bean class="org.example.MyBeanFactoryProcessor">
        <property name="editors">
            <map>
                <entry key="org.example.User" value="org.example.UserEditor"></entry>
            </map>
        </property>
    </bean>
    <bean class="org.example.MyBeanPostProcessor"></bean>
</beans>
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
    Map<Class,Class <? extends PropertyEditor>> editors;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
        System.out.println("postProcessBeanFactory");
        for (Map.Entry<Class,Class<? extends PropertyEditor>> entry: editors.entrySet()){
            factory.registerCustomEditor(entry.getKey(),entry.getValue());
        }
    }

    public Map<Class, Class<? extends PropertyEditor>> getEditors() {
        return editors;
    }

    public void setEditors(Map<Class, Class<? extends PropertyEditor>> editors) {
        this.editors = editors;
    }
}

內置容器后置處理器

  • CustomEditorConfigurer 來 實現改造練習1
    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="customEditors">
            <map>
                <entry key="org.example.User" value="org.example.UserEditor"></entry>
            </map>
        </property>
    </bean>
  • PropertyPlaceholderConfigurer 用來讀取屬性文件,以及常用的類型轉換
  • applicationContext.xml
<?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 class="org.example.User"></bean>

    <bean id="bean1" class="org.example.Bean1" init-method="toString">
        <property name="user" value="[xixi-boy]"></property>
        <property name="tag" value="${tag}"></property>
    </bean>

    <bean class="org.example.MyBeanPostProcessor"></bean>

    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <property name="customEditors">
            <map>
                <entry key="org.example.User" value="org.example.UserEditor"></entry>
            </map>
        </property>
    </bean>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:user.properties"></property>
    </bean>
</beans>

  • user.propperties
tag=Yeah!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM