日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java SSM4——Spring

發布時間:2025/3/12 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java SSM4——Spring 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java SSM4——Spring

Spring是一個輕量級的控制反轉(IoC)和面向切面(AOP)的容器(框架)

Spring的優勢

  • 方便解耦,簡化開發
    • Spring就是一個容器,可以將所有對象創建和關系維護交給Spring管理 什么是耦合度?對象之間的關系,通常說當一個模塊(對象)更改時也需要更改其他模塊(對象),這就是耦合,耦合度過高會使代碼的維護成本增加。要盡量解耦
  • AOP編程的支持
    • Spring提供面向切面編程,方便實現程序進行權限攔截,運行監控等功能
  • 聲明式事務的支持
    • 通過配置完成事務的管理,無需手動編程
  • 方便測試,降低JavaEE API的使用
    • Spring對Junit4支持,可以使用注解測試
  • 方便集成各種優秀框架
    • 不排除各種優秀的開源框架,內部提供了對各種優秀框架的直接支持

1、IOC

Inverse Of Control:控制反轉:配置文件(解除硬編碼)+反射(解除編譯器依賴)

  • 控制:在java中指的是對象的控制權限(創建、銷毀)
  • 反轉:指的是對象控制權由原來 由開發者在類中手動控制交由Spring管理

2、AOP

Aspect Oriented Programming:面向切面編程:動態代理(方法增強)

3、快速入門

默認為maven項目

3.1、導入依賴

<dependencies><!--spring--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.9</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency> </dependencies>

3.2、Spring核心配置文件

如無特殊需求,我們默認spring核心配置文件名為applicationContent.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="HelloSpring" class="club.winkto.bean.HelloSpring"></bean> </beans>

3.3、書寫簡單的類

public class HelloSpring {public void hellospring(){System.out.println("hello spring!");} }

3.4、測試

@Test public void test(){ClassPathXmlApplicationContext classPathXmlApplicationContext =new ClassPathXmlApplicationContext("applicationContent.xml");HelloSpring hellospring = classPathXmlApplicationContext.getBean("hellospring", HelloSpring.class);hellospring.hellospring(); }

4、Spring API

BeanFactory也可以完成ApplicationContext完成的事情,為什么我們要選擇ApplicationContext?

BeanFactory:在第一次調用getBean()方法時,創建指定對象的實例

ApplicationContext:在spring容器啟動時,加載并創建所有對象的實例

4.1、常用實現類

  • ClassPathXmlApplicationContext 它是從類的根路徑下加載配置文件 推薦使用這種
  • FileSystemXmlApplicationContext 它是從磁盤路徑上加載配置文件,配置文件可以在磁盤的任意位置
  • AnnotationConfigApplicationContext 當使用注解配置容器對象時,需要使用此類來創建 spring 容器,它用來讀取注解

5、Spring IOC

5.1、bean

5.1.1、基礎使用

<bean id="" class=""></bean>
  • id:Bean實例在Spring容器中的唯一標識
  • class:Bean的全限定名
  • 默認情況下它調用的是類中的 無參構造函數,如果沒有無參構造函數則不能創建成功

5.1.2、scope屬性

<bean id="" class="" scope=""></bean>
  • singleton:單例(默認)
    • 對象創建:當應用加載,創建容器時,對象就被創建了
    • 對象運行:只要容器在,對象一直活著
    • 對象銷毀:當應用卸載,銷毀容器時,對象就被銷毀了
  • prototype:多例
    • 對象創建:當使用對象時,創建新的對象實例
    • 對象運行:只要對象在使用中,就一直活著
    • 對象銷毀:當對象長時間不用時,被 Java 的垃圾回收器回收了

5.1.3、生命周期的配置

<bean id="" class="包名.類名" init-method="指定class的方法" destroy-method="指定class的方法"></bean>
  • init-method:指定類中的初始化方法名稱
  • destroy-method:指定類中銷毀方法名稱

5.1.4、Bean實例化的三種方式

5.1.4.1、構造器實例化

spring容器通過bean對應的默認的構造函數來實例化bean。

上述即是

5.1.4.2、 靜態工廠方式實例化
<bean id="" class="包名.類名" factory-method="指定class的方法" />

首先創建一個靜態工廠類,在類中定義一個靜態方法創建實例。

靜態工廠類及靜態方法:

public class MyUserDaoFactory{//靜態方法,返回UserDaoImpl的實例對象public static UserDaoImpl createUserDao{return new UserDaoImpl();} }

xml配置文件

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd"> <beans><!-- 將指定對象配置給spring,讓spring創建其實例 --><bean id="userDao" class="com.ioc.MyUserDaoFactory" factory-method="createUserDao"/> </beans>
5.1.4.3、 實例工廠方式實例化
<bean id="工廠類id" class="包名.類名"/> <bean id="" factory-bean="工廠類id" factorymethod="工廠類id里的方法"/>

該種方式的工廠類中,不再使用靜態方法創建Bean實例,而是采用直接創建Bean實例的方式。同時在配置文件中,需要實例化的Bean也不是通過class屬性直接指向其實例化的類,而是通過factory-bean屬性配置一個實例工廠,然后使用factory-method屬性確定使用工廠中哪個方法。

工廠類方法:

public class MyBeanFactory{public MyBeanFactory(){System.out.println("this is a bean factory");}public UserDaoImpl createUserDao(){return new UserDaoImpl();} }

xml配置文件:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd"> <beans><!-- 配置工廠 --><bean id="myBeanFactory" class="com.ioc.MyBeanFactory"/><!-- 使用factory-bean屬性配置一個實例工廠,使用factory-method屬性確定工廠中的哪個方法 --><bean id="userDao" factory-bean="myBeanFactory" factory-method="createUserDao"/> </beans>

主函數

public class Client {public static void main(String[] args) {// TODO Auto-generated method stub//此處定義xml文件放置的位置為src目錄下的com/xml目錄下String path = "com/xml/bean.xml";ApplicationContext application = new ClassPathXmlApplicationContext(path);UserDaoImpl userDao = (UserDaoImpl) application.getBean("userDao");userDao.sayHello(); //調用UserDaoImpl類的sayHello方法} }

5.1.5、別名

5.1.5.1、alias標簽
<alias name="hello" alias="hello1"></alias>
5.1.5.2、bean標簽name屬性
<bean id="HelloSpring" name="hello2 h2,h3;h4" class="club.winkto.bean.HelloSpring"></bean>

可寫多個別名,分隔符為空格,逗號,分號均可

5.2、依賴注入(DI)

Spring 框架核心 IOC 的具體實現

5.2.1、構造方法

mapper

public interface WinktoMapper {void mapper(); } public class WinktoMapperImpl implements WinktoMapper {public void mapper() {System.out.println("假裝自己有了數據庫查詢");} }

service

public interface WinktoService {void service(); } public class WinktoServiceImpl implements WinktoService {private int a;private WinktoMapperImpl winktoMapper;private Object[] arrays;private List list;private Map<String,Object> map;private Set set;private Properties properties;public WinktoServiceImpl(int a, WinktoMapperImpl winktoMapper, Object[] arrays, List list, Map<String, Object> map, Set set, Properties properties) {this.a = a;this.winktoMapper = winktoMapper;this.arrays = arrays;this.list = list;this.map = map;this.set = set;this.properties = properties;}public void service() {System.out.println("假裝自己開啟了事務");winktoMapper.mapper();System.out.println("=================");System.out.println(toString());System.out.println("=================");System.out.println("假裝自己提交了事務");}@Overridepublic String toString() {return "WinktoServiceImpl{" +"a=" + a +", winktoMapper=" + winktoMapper +", arrays=" + arrays +", list=" + list +", map=" + map +", set=" + set +", properties=" + properties +'}';} }

aplicationContent.xml

<bean id="winktoMapper" class="club.winkto.mapper.WinktoMapperImpl"></bean><bean id="winktoService" class="club.winkto.service.WinktoServiceImpl"><!--<constructor-arg index="0" value="12"></constructor-arg>--><!--<constructor-arg index="1" ref="winktoMapper"></constructor-arg>--><!--<constructor-arg index="2">--><!-- <array>--><!-- <value>1</value>--><!-- <ref bean="winktoMapper"></ref>--><!-- </array>--><!--</constructor-arg>--><!--<constructor-arg index="3">--><!-- <list>--><!-- <value>2</value>--><!-- <ref bean="winktoMapper"></ref>--><!-- </list>--><!--</constructor-arg>--><!--<constructor-arg index="4">--><!-- <map>--><!-- <entry key="name" value="zhangsan"></entry>--><!-- <entry key="service" value-ref="winktoMapper"></entry>--><!-- </map>--><!--</constructor-arg>--><!--<constructor-arg index="5">--><!-- <set>--><!-- <value>3</value>--><!-- <ref bean="winktoMapper"></ref>--><!-- </set>--><!--</constructor-arg>--><!--<constructor-arg index="6">--><!-- <props>--><!-- <prop key="name">zhangsan</prop>--><!-- </props>--><!--</constructor-arg>--><constructor-arg name="a" value="12"></constructor-arg><constructor-arg name="winktoMapper" ref="winktoMapper"></constructor-arg><constructor-arg name="arrays"><array><value>1</value><ref bean="winktoMapper"></ref></array></constructor-arg><constructor-arg name="list"><list><value>2</value><ref bean="winktoMapper"></ref></list></constructor-arg><constructor-arg name="map"><map><entry key="name" value="zhangsan"></entry><entry key="service" value-ref="winktoMapper"></entry></map></constructor-arg><constructor-arg name="set"><set><value>3</value><ref bean="winktoMapper"></ref></set></constructor-arg><constructor-arg name="properties"><props><prop key="name">zhangsan</prop></props></constructor-arg></bean> </beans>

測試

@Test public void test(){ClassPathXmlApplicationContext classPathXmlApplicationContext =new ClassPathXmlApplicationContext("applicationContent.xml");WinktoService winktoService = classPathXmlApplicationContext.getBean("winktoService", WinktoService.class);winktoService.service(); }

5.2.2、set

mapper

public interface WinktoMapper {void mapper(); } public class WinktoMapperImpl implements WinktoMapper {public void mapper() {System.out.println("假裝自己有了數據庫查詢");} }

service

public interface WinktoService {void service(); } public class WinktoServiceImpl implements WinktoService {private int a;private WinktoMapperImpl winktoMapper;private Object[] arrays;private List list;private Map<String,Object> map;private Set set;private Properties properties;public int getA() {return a;}public void setA(int a) {this.a = a;}public WinktoMapperImpl getWinktoMapper() {return winktoMapper;}public void setWinktoMapper(WinktoMapperImpl winktoMapper) {this.winktoMapper = winktoMapper;}public Object[] getArrayList() {return arrays;}public void setArrayList(Object[] arrays) {this.arrays = arrays;}public List getList() {return list;}public void setList(List list) {this.list = list;}public Map<String, Object> getMap() {return map;}public void setMap(Map<String, Object> map) {this.map = map;}public Set getSet() {return set;}public void setSet(Set set) {this.set = set;}public Properties getProperties() {return properties;}public void setProperties(Properties properties) {this.properties = properties;}public void service() {System.out.println("假裝自己開啟了事務");winktoMapper.mapper();System.out.println("=================");System.out.println(toString());System.out.println("=================");System.out.println("假裝自己提交了事務");}@Overridepublic String toString() {return "WinktoServiceImpl{" +"a=" + a +", winktoMapper=" + winktoMapper +", arrays=" + arrays +", list=" + list +", map=" + map +", set=" + set +", properties=" + properties +'}';} }

aplicationContent.xml

<bean id="winktoMapper" class="club.winkto.mapper.WinktoMapperImpl"> </bean> <bean id="winktoService" class="club.winkto.service.WinktoServiceImpl"><property name="a" value="12"></property><property name="winktoMapper" ref="winktoMapper"></property><property name="arrayList"><array><value>1</value><ref bean="winktoMapper"></ref></array></property><property name="list"><list><value>2</value><ref bean="winktoMapper"></ref></list></property><property name="map"><map><entry key="name" value="zhangsan"></entry><entry key="service" value-ref="winktoMapper"></entry></map></property><property name="set"><set><value>3</value><ref bean="winktoMapper"></ref></set></property><property name="properties"><props><prop key="name">zhangsan</prop></props></property> </bean>

測試

@Test public void test(){ClassPathXmlApplicationContext classPathXmlApplicationContext =new ClassPathXmlApplicationContext("applicationContent.xml");WinktoService winktoService = classPathXmlApplicationContext.getBean("winktoService", WinktoService.class);winktoService.service(); }

5.2.3、p命名空間(簡單示范)

導入約束

xmlns:p="http://www.springframework.org/schema/p"

mapper

public interface WinktoMapper {void mapper(); } public class WinktoMapperImpl implements WinktoMapper {public void mapper() {System.out.println("假裝自己有了數據庫查詢");} }

service

public interface WinktoService {void service(); } public class WinktoServiceImpl implements WinktoService {private WinktoMapperImpl winktoMapper;public WinktoMapperImpl getWinktoMapper() {return winktoMapper;}public void setWinktoMapper(WinktoMapperImpl winktoMapper) {this.winktoMapper = winktoMapper;}public void service() {System.out.println("假裝自己開啟了事務");winktoMapper.mapper();System.out.println("假裝自己提交了事務");} }

aplicationContent.xml

  • 對于bean引用用p:xxx-ref
  • 否則使用p:xxx
<bean id="winktoMapper" class="club.winkto.mapper.WinktoMapperImpl"> </bean> <bean id="winktoService" class="club.winkto.service.WinktoServiceImpl" p:winktoMapper-ref="winktoMapper"> </bean>

測試

@Test public void test(){ClassPathXmlApplicationContext classPathXmlApplicationContext =new ClassPathXmlApplicationContext("applicationContent.xml");WinktoService winktoService = classPathXmlApplicationContext.getBean("winktoService", WinktoService.class);winktoService.service(); }

5.2.4、c命名空間(簡單示范)

導入約束

xmlns:c="http://www.springframework.org/schema/c"

mapper

public interface WinktoMapper {void mapper(); } public class WinktoMapperImpl implements WinktoMapper {public void mapper() {System.out.println("假裝自己有了數據庫查詢");} }

service

public interface WinktoService {void service(); } public class WinktoServiceImpl implements WinktoService {private WinktoMapperImpl winktoMapper;public WinktoMapperImpl getWinktoMapper() {return winktoMapper;}public void setWinktoMapper(WinktoMapperImpl winktoMapper) {this.winktoMapper = winktoMapper;}public void service() {System.out.println("假裝自己開啟了事務");winktoMapper.mapper();System.out.println("假裝自己提交了事務");} }

aplicationContent.xml

  • 對于bean引用用c:xxx-ref
  • 否則使用c:xxx
  • c命名空間可以額外使用c:_0-ref
<bean id="winktoMapper" class="club.winkto.mapper.WinktoMapperImpl"> </bean> <!--<bean id="winktoService" class="club.winkto.service.WinktoServiceImpl" c:winktoMapper-ref="winktoMapper">--> <!--</bean>--> <bean id="winktoService" class="club.winkto.service.WinktoServiceImpl" c:_0-ref="winktoMapper"> </bean>

測試

@Test public void test(){ClassPathXmlApplicationContext classPathXmlApplicationContext =new ClassPathXmlApplicationContext("applicationContent.xml");WinktoService winktoService = classPathXmlApplicationContext.getBean("winktoService", WinktoService.class);winktoService.service(); }

5.3、配置文件模塊化

5.3.1、配置文件并列

ClassPathXmlApplicationContext classPathXmlApplicationContext =new ClassPathXmlApplicationContext("applicationContent.xml","beans.xml");

5.3.2、主從配置文件

在applicationContent.xml導入beans.xml

<import resource="beans.xml"/>

6、Spring注解開發(IOC部分)

Spring是輕代碼而重配置的框架,配置比較繁重,影響開發效率,所以注解開發是一種趨勢,注解代 替xml配置文件可以簡化配置,提高開發效率

開啟注解掃描

<!--注解的組件掃描--> <context:component-scan base-package="club.winkto"></context:component-scan>

6.1、注冊bean

注解說明
@Component使用在類上用于實例化Bean
@Controller使用在web層類上用于實例化Bean
@Service使用在service層類上用于實例化Bean
@Repository使用在dao層類上用于實例化Bean

6.2、依賴注入

注解說明
@Autowired使用在字段上用于根據類型依賴注入(先根據type,類型不唯一根據name自動裝配的)
@Qualifier結合@Autowired一起使用,根據名稱進行依賴注入
@Resource相當于@Autowired+@Qualifier,按照名稱進行注入(很少用且jdk11在spring核心包不包含此注解)
@Value注入普通屬性(也可以注入spring配置文件里的其他普通屬性使用${},上面三個注入引用類型)

6.3、初始銷毀

注解說明
@PostConstruct使用在方法上標注該方法是Bean的初始化方法
@PreDestroy使用在方法上標注該方法是Bean的銷毀方法

6.4、新注解

注解說明
@Configuration用于指定當前類是一個Spring 配置類,當創建容器時會從該類上加載注解
@Bean使用在方法上,標注將該方法的返回值存儲到 Spring 容器中
@PropertySource用于加載 properties 文件中的配置
@ComponentScan用于指定 Spring 在初始化容器時要掃描的包
@Import用于導入其他配置類

6.5、注解快速入門

mapper

public interface WinktoMapper {void mapper(); } @Repository("winktoMapper") public class WinktoMapperImpl implements WinktoMapper {public void mapper() {System.out.println("假裝自己有了數據庫查詢");} }

service

public interface WinktoService {void service(); } @Service("winktoService") public class WinktoServiceImpl implements WinktoService {@Value("12")private int a;@Autowiredprivate WinktoMapperImpl winktoMapper;public WinktoServiceImpl() {}public WinktoServiceImpl(int a, WinktoMapperImpl winktoMapper) {this.a = a;this.winktoMapper = winktoMapper;}public int getA() {return a;}public void setA(int a) {this.a = a;}public WinktoMapperImpl getWinktoMapper() {return winktoMapper;}public void setWinktoMapper(WinktoMapperImpl winktoMapper) {this.winktoMapper = winktoMapper;}public void service() {System.out.println("假裝自己開啟了事務");winktoMapper.mapper();System.out.println("=================");System.out.println(toString());System.out.println("=================");System.out.println("假裝自己提交了事務");}@Overridepublic String toString() {return "WinktoServiceImpl{" +"a=" + a +", winktoMapper=" + winktoMapper +'}';} }

aplicationContent.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"xmlns:p="http://www.springframework.org/schema/p"xmlns:c="http://www.springframework.org/schema/c"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><!--注解的組件掃描--><context:component-scan base-package="club.winkto"></context:component-scan> </beans>

測試

@Test public void test(){ClassPathXmlApplicationContext classPathXmlApplicationContext =new ClassPathXmlApplicationContext("applicationContent.xml");WinktoService winktoService = classPathXmlApplicationContext.getBean("winktoService", WinktoService.class);winktoService.service(); }

6.6、純注解開發

導入依賴

<dependencies><!--spring--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.9</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.6</version></dependency> </dependencies>

mapper

public interface WinktoMapper {void mapper(); } @Repository("winktoMapper") public class WinktoMapperImpl implements WinktoMapper {@Value("${name}")private String name;public void mapper() {System.out.println(name);System.out.println("假裝自己有了數據庫查詢");} }

service

public interface WinktoService {void service(); } @Service("winktoService") public class WinktoServiceImpl implements WinktoService {@Value("12")private int a;@Autowiredprivate WinktoMapperImpl winktoMapper;public WinktoServiceImpl() {}public WinktoServiceImpl(int a, WinktoMapperImpl winktoMapper) {this.a = a;this.winktoMapper = winktoMapper;}public int getA() {return a;}public void setA(int a) {this.a = a;}public WinktoMapperImpl getWinktoMapper() {return winktoMapper;}public void setWinktoMapper(WinktoMapperImpl winktoMapper) {this.winktoMapper = winktoMapper;}public void service() {System.out.println("假裝自己開啟了事務");winktoMapper.mapper();System.out.println("=================");System.out.println(toString());System.out.println("=================");System.out.println("假裝自己提交了事務");}@Overridepublic String toString() {return "WinktoServiceImpl{" +"a=" + a +", winktoMapper=" + winktoMapper +'}';} }

config

@Configuration @PropertySource("classpath:database.properties") public class WinktoMapperConfig {@Value("${name}")private String name; } @Configuration @ComponentScan("club.winkto") @Import(WinktoMapperConfig.class) public class WinktoConfig {@Beanpublic ObjectMapper objectMapper(){return new ObjectMapper();} }

測試

@Test public void test() throws JsonProcessingException {AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(WinktoConfig.class);WinktoService winktoService = annotationConfigApplicationContext.getBean("winktoService", WinktoService.class);ObjectMapper objectMapper = annotationConfigApplicationContext.getBean("objectMapper", ObjectMapper.class);System.out.println(objectMapper.writeValueAsString(winktoService));winktoService.service(); }

6.7、Spring整合junit

導入依賴

<dependencies><!--spring--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.9</version></dependency><!--spring-test--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.9</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.6</version></dependency> </dependencies>

修改Test類

@RunWith(SpringJUnit4ClassRunner.class) //@ContextConfiguration(value = {"classpath:applicationContext.xml"}) @ContextConfiguration(classes = {WinktoConfig.class}) public class MyTest {@Autowiredprivate WinktoService winktoService;@Autowiredprivate ObjectMapper objectMapper;@Testpublic void test() throws JsonProcessingException {System.out.println(objectMapper.writeValueAsString(winktoService));winktoService.service();} }

7、動態代理

7.1、JDK動態代理

基于接口的動態代理技術:利用攔截器(必須實現invocationHandler)加上反射機制生成 一個代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理,從而實現方法增強

7.2.1、JDK動態代理實現

service

public interface CRUD {void select();void insert();void update();void delete(); } @Service public class CRUDService implements CRUD {public void select() {System.out.println("假裝自己執行了select");}public void insert() {System.out.println("假裝自己執行了insert");}public void update() {System.out.println("假裝自己執行了update");}public void delete() {System.out.println("假裝自己執行了delete");} }

config

@Configuration @ComponentScan("cn.winkto") public class WinktoConfig {@Bean("objectMapper")public ObjectMapper getObjectMapper(){return new ObjectMapper();} }

代理

@Component public class JDKProxy {public Object proxy(final CRUDService crudService){return Proxy.newProxyInstance(crudService.getClass().getClassLoader(), crudService.getClass().getInterfaces(), new InvocationHandler() {public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("代理前");Object invoke = method.invoke(crudService, args);System.out.println("代理后");return invoke;}});} }

測試

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {WinktoConfig.class}) public class MyTest {@Autowiredprivate JDKProxy jdkProxy;@Autowiredprivate CRUDService crudService;@Testpublic void test(){CRUD proxy = (CRUD) jdkProxy.proxy(crudService);proxy.select();} }

7.2、CGLIB代理

基于父類的動態代理技術:動態生成一個要代理的子類,子類重寫要代理的類的所有不是 final的方法。在子類中采用方法攔截技術攔截所有的父類方法的調用,順勢織入橫切邏輯,對方法進行 增強

7.2.1、CGLIB代理的實現

service

public interface CRUD {void select();void insert();void update();void delete(); } @Service public class CRUDService implements CRUD {public void select() {System.out.println("假裝自己執行了select");}public void insert() {System.out.println("假裝自己執行了insert");}public void update() {System.out.println("假裝自己執行了update");}public void delete() {System.out.println("假裝自己執行了delete");} }

config

@Configuration @ComponentScan("cn.winkto") public class WinktoConfig {@Bean("objectMapper")public ObjectMapper getObjectMapper(){return new ObjectMapper();} }

代理

@Component public class CglibProxy {public Object proxy(final CRUDService crudService){return Enhancer.create(crudService.getClass(), new MethodInterceptor() {public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("代理前");Object invoke = method.invoke(crudService, objects);System.out.println("代理后");return invoke;}});} }

測試

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {WinktoConfig.class}) public class MyTest {@Autowiredprivate JDKProxy jdkProxy;@Autowiredprivate CglibProxy cglibProxy;@Autowiredprivate CRUDService crudService;@Testpublic void test1(){CRUD proxy = (CRUD) cglibProxy.proxy(crudService);proxy.select();} }

8、Spring AOP

AOP 是 OOP(面向對象編程) 的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率

  • 在程序運行期間,在不修改源碼的情況下對方法進行功能增強
  • 邏輯清晰,開發核心業務的時候,不必關注增強業務的代碼
  • 減少重復代碼,提高開發效率,便于后期維護

8.1、Aop術語解釋

  • Target(目標對象):代理的目標對象
  • Proxy (代理):一個類被 AOP 織入增強后,就產生一個結果代理類
  • Joinpoint(連接點):所謂連接點是指那些可以被攔截到的點。在spring中,這些點指的是方法,因為 spring只支持方法類型的連接點
  • Pointcut(切入點):所謂切入點是指我們要對哪些 Joinpoint 進行攔截的定義
  • Advice(通知/ 增強):所謂通知是指攔截到 Joinpoint 之后所要做的事情就是通知 分類:前置通知、后置通知、異常通知、最終通知、環繞通知
  • Aspect(切面):是切入點和通知(引介)的結合
  • Weaving(織入):是指把增強應用到目標對象來創建新的代理對象的過程。spring采用動態代理織 入,而AspectJ采用編譯期織入和類裝載期織入

8.2、Aop快速入門

導入依賴

<dependencies><!--spring--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.9</version></dependency><!--spring-test--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.9</version><scope>test</scope></dependency><!--aop--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.6</version></dependency> </dependencies>

service

public interface CRUD {void select();void insert();void update();void delete(); } public class CRUDService implements CRUD {public void select() {System.out.println("假裝自己執行了select");}public void insert() {System.out.println("假裝自己執行了insert");}public void update() {System.out.println("假裝自己執行了update");}public void delete() {System.out.println("假裝自己執行了delete");} }

aop

public class CRUDAdvice {public void before(){System.out.println("前置通知");}public void afterReturning(){System.out.println("后置通知");}public void afterThrowing(){System.out.println("異常通知");}public void after(){System.out.println("最終通知");}public void around(ProceedingJoinPoint ProceedingJoinPoint){System.out.println("環繞開始");try {ProceedingJoinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println("環繞結束");} }

applicationContent.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"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="crudService" class="cn.winkto.service.CRUDService"></bean><bean id="crudAdvice" class="cn.winkto.aop.CRUDAdvice"></bean><aop:config><aop:aspect ref="crudAdvice"><aop:before method="before" pointcut="execution(* cn.winkto.service.CRUDService.*(..))"></aop:before><aop:after method="afterReturning" pointcut="execution(* cn.winkto.service.CRUDService.*(..))"></aop:after></aop:aspect></aop:config> </beans>

測試

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(value = {"classpath:applicationContent.xml"}) public class MyTest {@Autowiredprivate CRUD crud;@Testpublic void test(){crud.select();} }

8.3、Aop詳解

8.3.1、切點表達式

execution([修飾符] 返回值類型 包名.類名.方法名(參數))
  • 訪問修飾符可以省略
  • 返回值類型、包名、類名、方法名可以使用星號 * 代替,代表任意
  • 包名與類名之間一個點 . 代表當前包下的類,兩個點 … 表示當前包及其子包下的類
  • 參數列表可以使用兩個點 … 表示任意個數,任意類型的參數列表

8.3.2、切點表達式的抽取

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="crudService" class="cn.winkto.service.CRUDService"></bean><bean id="crudAdvice" class="cn.winkto.aop.CRUDAdvice"></bean><aop:config><aop:aspect ref="crudAdvice"><aop:pointcut id="point1" expression="execution(* cn.winkto.service.CRUDService.*(..))"/><aop:before method="before" pointcut-ref="point1"></aop:before><aop:after method="afterReturning" pointcut-ref="point1"></aop:after></aop:aspect></aop:config> </beans> <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="crudService" class="cn.winkto.service.CRUDService"></bean><bean id="crudAdvice" class="cn.winkto.aop.CRUDAdvice"></bean><aop:config><aop:pointcut id="point1" expression="execution(* cn.winkto.service.CRUDService.*(..))"/><aop:aspect ref="crudAdvice"><aop:before method="before" pointcut-ref="point1"></aop:before><aop:after method="afterReturning" pointcut-ref="point1"></aop:after></aop:aspect></aop:config> </beans>

8.3.3、通知類型

<aop:通知類型 method=“通知類中方法名” pointcut=“切點表達式"></aop:通知類型> 名稱標簽說明
前置通知<aop:before>用于配置前置通知,指定增強的方法在切入點方法之前執行
后置通知<aop:afterReturning>用于配置后置通知。指定增強的方法在切入點方法之后執行
異常通知<aop:afterThrowing>用于配置異常通知。指定增強的方法出現異常后執行
最終通知<aop:after>用于配置最終通知。無論切入點方法執行時是否有異常,都會執行
環繞通知<aop:around>用于配置環繞通知。開發者可以手動控制增強代碼在什么時候執行

后置通知與異常通知互斥,環繞通知一般獨立使用

9、Spring注解開發(AOP部分)

導入依賴

<dependencies><!--spring--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.9</version></dependency><!--spring-test--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.9</version><scope>test</scope></dependency><!--aop--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.6</version></dependency> </dependencies>

service

public interface CRUD {void select();void insert();void update();void delete(); } public class CRUDService implements CRUD {public void select() {System.out.println("假裝自己執行了select");}public void insert() {System.out.println("假裝自己執行了insert");}public void update() {System.out.println("假裝自己執行了update");}public void delete() {System.out.println("假裝自己執行了delete");} }

aop

@Component //標注為切面類 @Aspect public class CRUDAdvice {@Pointcut("execution(* cn.winkto.service.CRUDService.*(..))")public void point(){}@Before("point()")public void before(){System.out.println("前置通知");}@AfterReturning("point()")public void afterReturning(){System.out.println("后置通知");}public void afterThrowing(){System.out.println("異常通知");}public void after(){System.out.println("最終通知");}public void around(ProceedingJoinPoint ProceedingJoinPoint){System.out.println("環繞開始");try {ProceedingJoinPoint.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}System.out.println("環繞結束");} }

config

@Configuration @ComponentScan("cn.winkto") //開啟自動aop代理 @EnableAspectJAutoProxy public class WinktoConfig {@Bean("objectMapper")public ObjectMapper getObjectMapper(){return new ObjectMapper();} }

測試

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {WinktoConfig.class}) public class MyTest {@Autowiredprivate CRUD crud;@Testpublic void test(){crud.select();} }

10、Spring事務

  • 編程式事務:直接把事務的代碼和業務代碼耦合到一起,在實際開發中不用(下文不進行詳細闡述)
  • 聲明式事務:采用配置的方式來實現的事務控制,業務代碼與事務代碼實現解耦合

10.1、聲明式事務(基于XML,整合mybatis)

實體類

public class Person {private int pid;private String pname;private String ppassword; }

mapper

public interface PersonMapper {List<Person> selectPerson(); } public class PersonMapperImpl implements PersonMapper {private SqlSession sqlSession;public PersonMapperImpl(SqlSession sqlSession) {this.sqlSession = sqlSession;}public List<Person> selectPerson() {return sqlSession.getMapper(PersonMapper.class).selectPerson();} }

映射文件

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.winkto.mapper.PersonMapper"><select id="selectPerson" resultType="Person">select * from person</select> </mapper>

數據庫配置文件

driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai user=root password=blingbling123.

mybatis配置文件

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings><typeAliases><package name="cn.winkto.bean"></package></typeAliases><mappers><package name="cn.winkto.mapper"/></mappers> </configuration>

spring配置文件

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--開啟注解掃描--><context:component-scan base-package="cn.winkto" /><context:property-placeholder location="classpath:database.properties"/><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${user}"/><property name="password" value="${password}"/></bean><!--sqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="configLocation" value="mybatis-config.xml" /></bean><!--sqlsession--><bean id="sqlsession" class="org.mybatis.spring.SqlSessionTemplate"><constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" /></bean><bean id="personMapper" class="cn.winkto.mapper.PersonMapperImpl"><constructor-arg name="sqlSession" ref="sqlsession" /></bean><!--事務管理器--><bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><constructor-arg name="dataSource" ref="dataSource" /></bean><!--通知增強--><tx:advice id="txAdvice" transaction-manager="tx"><tx:attributes><tx:method name="*"/></tx:attributes></tx:advice><!--織入事務--><aop:config><aop:pointcut id="point" expression="execution(* cn.winkto.mapper.PersonMapperImpl.*(..))" /><aop:advisor advice-ref="txAdvice" pointcut-ref="point" /></aop:config> </beans>

測試

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(value = {"classpath:applicationContent.xml"}) public class MyTest {@Autowiredprivate PersonMapper personMapper;@Testpublic void test(){System.out.println(personMapper.selectPerson());} }

10.1.1、 事務參數的配置詳解

<tx:method name="selectPerson" isolation="REPEATABLE_READ" propagation="REQUIRED" timeout="-1" read-only="false"/>
  • name:切點方法名稱(可以使用*做匹配,類似于模糊查詢)
  • isolation:事務的隔離級別
  • propogation:事務的傳播行為
  • timeout:超時時間
  • read-only:是否只讀

10.2、聲明式事務(基于注解,整合mybatis)

實體類

public class Person {private int pid;private String pname;private String ppassword; }

數據庫配置文件

driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone =Asia/Shanghai user=root password=blingbling123.

mapper

public interface PersonMapper {List<Person> selectPerson(); } @Repository("personMapper") public class PersonMapperImpl implements PersonMapper {@Autowiredprivate SqlSessionTemplate sqlSession;public PersonMapperImpl(SqlSessionTemplate sqlSession) {this.sqlSession = sqlSession;}//配置事務屬性(可放置在類上,k)@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout = -1,readOnly = true)public List<Person> selectPerson() {return sqlSession.getMapper(PersonMapper.class).selectPerson();} }

映射文件

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.winkto.mapper.PersonMapper"><select id="selectPerson" resultType="Person">select * from person</select> </mapper>

mybatis配置文件

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings><typeAliases><package name="cn.winkto.bean"></package></typeAliases><mappers><package name="cn.winkto.mapper"/></mappers> </configuration>

config

@Configuration @EnableAspectJAutoProxy @EnableTransactionManagement @ComponentScan("cn.winkto") @PropertySource("classpath:database.properties")public class WinktoConfig {@Value("${driver}")private String driver;@Value("${url}")private String url;@Value("${user}")private String user;@Value("${password}")private String password;@Beanpublic DataSource dataSource(){DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName(driver);druidDataSource.setUrl(url);druidDataSource.setUsername(user);druidDataSource.setPassword(password);return druidDataSource;}@Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(@Autowired DataSource dataSource){SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));return sqlSessionFactoryBean;}@Bean("sqlSession")public SqlSessionTemplate sqlSessionTemplate(@Autowired SqlSessionFactoryBean sqlSessionFactoryBean) throws Exception {return new SqlSessionTemplate(sqlSessionFactoryBean.getObject());}@Beanpublic DataSourceTransactionManager dataSourceTransactionManager(){return new DataSourceTransactionManager(dataSource());} }

測試

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {WinktoConfig.class}) public class MyTest {@Autowiredprivate PersonMapper personMapper;@Testpublic void test(){System.out.println(personMapper.selectPerson());} }

總結

以上是生活随笔為你收集整理的Java SSM4——Spring的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。