1. 程式人生 > 其它 >Spring 框架的使用 1

Spring 框架的使用 1

技術標籤:java 相關javaspring


在這裡插入圖片描述

  Spring 是一個專案管理框架,簡化企業級開發,俗稱”膠水框架”。

  自定義工廠類做類的例項化。


// mypro.properties
userdao=com.baidu.day.text.dao.impl.UserDaoImpl

// MyUtils.java
public class MyUtils {

    public static Properties properties = null;

    static {
        InputStream resourceAsStream = MyUtils.class
.getClassLoader().getResourceAsStream("mypro.properties"); properties = new Properties(); try { properties.load(resourceAsStream); } catch (IOException e) { e.printStackTrace(); } } public static Object getObject(String beanName)
{ String property = properties.getProperty(beanName); try { Class<?> aClass = Class.forName(property); return aClass.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) {
e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } } // IUserDao.java public interface IUserDao { void show(); } // UserDaoImpl.java public class UserDaoImpl implements IUserDao { @Override public void show() { System.out.println("hello spring。"); } } // 測試 IUserDao userDao = (UserDaoImpl)MyUtils.getObject("userdao"); userDao.show();

  使用 Spring 做類的例項化。
  Spring 工廠特性。餓漢式建立。工廠建立之後,會將 Spring 配置檔案中的所有物件都建立完成(餓漢式)。提高程式執行效率。避免多次IO,減少物件建立時間。(概念接近連線池,一次性建立好,使用時直接獲取)。


// pom.xml

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.12.RELEASE</version>
    </dependency>
    
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.16</version>
    </dependency>
  </dependencies>

// spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
">

    <bean id="userDao" class="com.baidu.day.text.dao.impl.UserDaoImpl" />

</beans>


// 測試
 ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        IUserDao userDao = (IUserDao) ac.getBean("userDao");
        userDao.show();

  IDEA 新增程式碼模版。
  Preferences -> Editor -> File And Code Templates。

  單例和多例。

// spring.xml
<!--  scope="prototype" 多例,預設為單例 singleton -->
    <bean id="userDao" class="com.baidu.day.text.dao.impl.UserDaoImpl" scope="prototype" />


// 測試
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
IUserDao userDao1 = (IUserDao) ac.getBean("userDao");
IUserDao userDao2 = (IUserDao) ac.getBean("userDao");
IUserDao userDao3 = (IUserDao) ac.getBean("userDao");

System.out.println(userDao1);
System.out.println(userDao2);
System.out.println(userDao3);

  控制反轉。實際上是類的巢狀例項化。


// IUserService.java

public interface IUserService {
    void show();
}

// UserServiceImpl.java 
// 注意要寫set/get
@Data
public class UserServiceImpl implements IUserService {
    private IUserDao userDao;
    @Override
    public void show() {

        userDao.show();
        System.out.println("這是 service");
    }
}

// spring.xml

<bean id="userDao" class="com.baidu.day.text.dao.impl.UserDaoImpl" scope="prototype" />

// 1
    <bean id="userService" class="com.baidu.day.text.service.impl.UserServiceImpl" >
<!--      name 對應例項屬性名; ref,引用,對應例項的bean id  -->
        <property name="userDao" ref="userdao"></property>
    </bean>

// 2、3
<!--   autowire 自動寫入。byName,根據屬性名,引入的bean id 和 屬性名要一致;byType,根據屬性型別 -->
    <bean id="userService" class="com.baidu.day.text.service.impl.UserServiceImpl" autowire="byName">

    </bean>

// 測試
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        IUserService userService = (IUserService) ac.getBean("userService");
        userService.show();

  依賴注入。實際上就是初始化賦值。


@Data
public class Address {

    private Integer id;
    private String address;

}

// User.java

@Data
public class User {

    private Integer id;
    private String password;
    private String sex;
    private Integer age;

    private Date bornDate;
    private String[] hobbys;
    private Set<String> phones;
    private List<String> names;
    private Map<String,String> countries;
    private Properties files;
    /* 物件s */
    private Address address;

}


// spring.xml 部分程式碼

<!--  依賴注入   -->
    <bean id="user" class="com.baidu.day.text.entity.User">
<!--    使用set、get方法賦值    -->
        <property name="id" value="1"></property>
        <property name="password" value="123"></property>
        <property name="sex" value="男"></property>
        <property name="age" value="12"></property>

<!--     日期, 固定格式 xxxx/xx/xx -->
        <property name="bornDate" value="2021/1/21"></property>

<!--        陣列 -->
        <property name="hobbys">
            <array>
                <value>coding</value>
                <value>read</value>
                <value>write</value>
            </array>
        </property>

<!--        set -->
        <property name="phones">
            <set>
                <value>123</value>
                <value>234</value>
            </set>
        </property>

<!--       list -->
        <property name="names">
            <list>
                <value>admin</value>
                <value>張三</value>
            </list>
        </property>

<!--        map -->
        <property name="countries">
            <map>
                <entry key="cn">
                    <value>china</value>
                </entry>
                <entry key="usa">
                    <value>amarican</value>
                </entry>
            </map>
        </property>

<!--        properties -->
        <property name="files">
            <props>
                <prop key="username">admin</prop>
                <prop key="password">123</prop>
            </props>
        </property>

        <!--    物件 -->
        <property name="address">
            <bean class="com.baidu.day.text.entity.Address">
                <property name="id" value="1"></property>
                <property name="address" value="北京"></property>
            </bean>
        </property>
    </bean>


// 測試
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        User user = (User) ac.getBean("user");
        System.out.println(user);

  構造注入。


// Student.java
public class Student {

    private Integer id;
    private String name;
    private String sex;
    private Integer age;

    public Student(Integer id, String name, String sex, Integer age) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
}

// spring.xml
<!--   預設呼叫無參構造方法,沒有會報錯 -->
    <bean id="student" class="com.baidu.day.text.entity.Student">

<!--        根據引數名 -->
        <constructor-arg name="id" value="1"></constructor-arg>
        <constructor-arg name="name" value="admin"></constructor-arg>
        <constructor-arg name="sex" value="男"></constructor-arg>
        <constructor-arg name="age" value="12"></constructor-arg>

<!--       根據下標 -->
<!--        <constructor-arg index="0" value="1"></constructor-arg>-->
<!--        <constructor-arg index="1" value="admin"></constructor-arg>-->
<!--        <constructor-arg index="2" value="男"></constructor-arg>-->
<!--        <constructor-arg index="3" value="12"></constructor-arg>-->

<!--       根據引數個數 -->
<!--        <constructor-arg value="1"></constructor-arg>-->
<!--        <constructor-arg value="admin"></constructor-arg>-->
<!--        <constructor-arg value="男"></constructor-arg>-->
<!--        <constructor-arg value="12"></constructor-arg>-->

    </bean>

  物件初始化和銷燬。


// Address.java

@Data
public class Address {
    private Integer id;
    private String address;
    
    public void init(){
        System.out.println("初始化了");
    }

    public void destroy(){
        System.out.println("銷燬");
    }
}

// spring.xml
	<bean id="address" class="com.baidu.day.text.entity.Address" init-method="init" destroy-method="destroy">
        <property name="id" value="1"></property>
        <property name="address" value="深圳"></property>
    </bean>

  FactoryBean 建立複雜物件。


// MyConnection.java

public class MyConnection implements FactoryBean<Connection> {


    @Override
    public Connection getObject() throws Exception {

        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb1", "admin", "admin");
        return connection;
    }

    @Override
    public Class<?> getObjectType() {
        return Connection.class;
    }

    // 是否單例
    @Override
    public boolean isSingleton() {
        return false;
    }
}


// spring.xml
<!--  返回的是 getObject 返回的  -->
    <bean id="conn" class="com.baidu.day.text.utils.MyConnection"></bean>

// 測試
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        Connection connection = (Connection) ac.getBean("conn");
        System.out.println(connection);

  代理。就是找個中間人來做事。常用來回調資料。

  靜態代理。

// IFangDong.java
public interface IFangDong {
    void zufang();
}

// FangDongImpl.java
public class FangDongImpl implements IFangDong {


    @Override
    public void zufang() {
        System.out.println("租房");
        System.out.println("收錢");
    }
}

// ZuFangProxy.java 
// 代理
@Data
public class ZuFangProxy {

    private IFangDong fangDong = new FangDongImpl();

    public void zufang() {
        System.out.println("釋出資訊");
        System.out.println("找人看房");

        //
        fangDong.zufang();
    }
}

// 測試
ZuFangProxy z = new ZuFangProxy();
z.zufang();

  動態代理。


// DynamicProxy.java

public class DynamicProxy {

    public static void jdk() {
        // 主要對有實現介面的實現類進行動態代理的生成

        final FangDongImpl fangDong = new FangDongImpl();

        // 設定代理
        InvocationHandler in = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                System.out.println("釋出資訊");
                System.out.println("找人看房");
                fangDong.zufang();
                return null;
            }
        };

        // 生成代理類
        IFangDong o = (IFangDong) Proxy.newProxyInstance(DynamicProxy.class.getClassLoader(), fangDong.getClass().getInterfaces(), in);
        o.zufang();
        System.out.println(o.getClass());
    }

    public static void cglib() {
        // 主要應用於沒有實現介面的類,進行動態代理的生成
        final FangDongImpl fangDong = new FangDongImpl();

        Enhancer en = new Enhancer();

        en.setSuperclass(FangDongImpl.class);

        // 設定代理
        en.setCallback(new org.springframework.cglib.proxy.InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                System.out.println("釋出資訊");
                System.out.println("找人看房");
                fangDong.zufang();
                return null;
            }
        });

        // 生成代理類
        IFangDong o = (IFangDong) en.create();
        o.zufang();
        System.out.println(o.getClass());
    }

    public static void main(String[] args) {
        jdk();

        cglib();
    }

}

  AOP,Aspect Oriented Programming,面向切面程式設計。


// pom.xml 新增

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.1.16.RELEASE</version>
</dependency>


// MyBefore.java 

public class MyBefore implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("這個是aop前置增強");
        System.out.println("寫日誌");
    }
}


// spring.xml 部分程式碼 ,相關的類在上面例子中有
<!-- aop -->
    <bean id="fangdong" class="com.baidu.day.text.proxy.FangDongImpl"></bean>
    <bean id="zufangproxy" class="com.baidu.day.text.proxy.ZuFangProxy">
    <!-- 有屬性的引入一定要寫 set/get -->
       <property name="fangDong" ref="fangdong"></property>
    </bean>
<!--  宣告增強類  -->
    <bean id="mybefore" class="com.baidu.day.text.advice.MyBefore"></bean>

    <aop:config>
    	// 設定切點。zufang 所有同名方法都會走。
        <aop:pointcut id="myPointcut" expression="execution(* zufang(..))"/>
        <aop:advisor advice-ref="mybefore" pointcut-ref="myPointcut"></aop:advisor>
    </aop:config>

</beans>


// 測試
		ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");

		ZuFangProxy proxy = (ZuFangProxy)ac.getBean("zufangproxy");
		// class com.baidu.day.text.proxy.ZuFangProxy , proxy說明是代理類
        System.out.println(proxy.getClass());
        proxy.zufang();

// 列印,前置列印了兩次,是因為zufang 方法名匹配到兩次的原因
class com.baidu.day.text.proxy.ZuFangProxy$$EnhancerBySpringCGLIB$$e1f1afde

這個是aop前置增強
寫日誌
釋出資訊
找人看房
這個是aop前置增強
寫日誌
租房
收錢