Spring 框架的使用 1
阿新 • • 發佈:2021-01-22
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前置增強
寫日誌
租房
收錢