導入Spring使用的maven依賴:
<!--單元測試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--Spring依賴jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
applicationContext.xml (beans.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<import resource="spring-dao.xml"/>
<!--bean-->
<bean id="userMapper" class="com.kuang.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
假設我們使用Spring的IOC創建對象,默認創建的bean對象是用 無參方式 方式創建對象,如果我們要使用有參構造對象,那么請務必保證我們的對象是有 有參構造函數 的類,同時如果要用set方式注入的話也要保證我們所創建的對象的類的各個參數是有 Set 方法的類!!!
bean的配置:
<!-
id:bean的唯一標識符,也就是相當於我們學的對象名
class:bean對象所對應的全限定名:包名+類名
name:也是別名,而且name可以同時取多個別名
scope: 默認單例模式singleton創建對象
-->
<bean id="userT" class="com.kuang.pojo.UserT" name="user2 u2,u3;u4">
</bean>
有參構造創建對象方法:
<!--第一種,下標賦值 (也是我最推崇的方式了,我用就用這個即可,其他了解即可不列出了)-->
<bean id="user" class="com.kuang.pojo.User">
<constructor-arg index="0" value="狂神說Java"/>
</bean>
自動裝配
xml中實現自動裝配:
<bean id="cat" class="com.rui.pojo.Cat"/>
<bean id="dog" class="com.rui.pojo.Dog"/>
<!--
byName:會自動在容器上下文中查找,和自己對象set方法后面的值對應的beanid!
byType:會自動在容器上下文中查找,和自己對象屬性類型相同的bean!
-->
<bean id="people" class="com.rui.pojo.People" autowire="byType">
<property name="name" value="尹銳"/>
</bean>
<!--
小結:
-- byName的時候,需要保證所有bean的id唯一,並且這個bean需要和注入的屬性的set方法的值一致
-- byType的時候,需要保證所有bean的class唯一,並且這個bean需要和注入的屬性的類型一致
-->
使用注解實現自動裝配:
要使用注解須知:
- 導入約束 context約束
- 配置注解的支持:
<context:annotation-config/>
@Autowired
直接在屬性上用即可!也可以在set方式上使用!
使用Autowired我們可以不用使用Set方法了,前提是你這個自動裝配的屬性在IOC(Spring)容器中存在且符合名字(ByName)
測試代碼**:
public class People {
//如果顯式的定義了AutoWired的required屬性為false,說明這個對象可以為null,否則不允許為空
@Autowired(required = false)
@Qualifier(value = "cat111")
private Cat cat;
@Autowired
private Dog dog;
private String name;
}
如果@Autowired自動裝配的環境比較復雜,自動裝配無法通過一個注解【@Autowired】完成的時候、我們可以使用@Qualifier(value = "xxx")去配合@Autowired的使用,指定一個唯一的bean對象注入
@Resource注解
在java1.8以后使用這個java的原生注解需要加入依賴的jar包:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
使用:
public class people
{ @Resource(name="cat")
private Cat cat;
@Resource
private Dog dog;
}
小結:
@Autowired是屬於spring的注解,它所在的包org.springframework.beans.factory.annotation,它是按byType注入的,默認是要依賴的對象必須存在,看源碼就可以理解,boolean required() default true;可以看到默認值是true,如果需要允許依賴對象是null,那就@Autowired(required=false)就可以了。
如果我們想@Autowired按名稱裝配,可以結合@Qualifier注解一起使用
@Autowired
@Qualifier("user")
private User user;
@Resource默認通過byname的方式實現,如果找不到名字,則通過byType實現!如果兩個都找 不到的情況下,就報錯!
執行順序不同:@Autowired默認通過byType的方式實現 @Resource默認通過byname 的方式實現
使用注解開發 [重點]
在Spring4之后,要使用注解開發,必須要保證AOP包已經導入了 [此包已經包含在了spring-webmvc的包里面了]
使用注解需要導入context約束,增加注解的支持!,並且開啟注解的支持
bean屬性如何注入:
//兩種方法都行,在屬性和set方法上都可以使用注解進行屬性注入
@Component public class User {
//相當於 <property name="name" value="kuangshen"/>
@Value("kuangshen")
public String name;
//相當於 <property name="name" value="kuangshen"/>
@Value("kuangshen")
public void setName(String name)
{
this.name = name;
}
}
衍生的注解 :
@Component有幾個衍生注解,我們在web開發中,會按照mvc三層架構分層!
-
dao 【@Repository】
-
service 【@Service】
-
controller 【@Controller】
這四個注解功能都是一樣的,都是代表將某個類注冊到Spring中,裝配Bean
自動裝配:
@Autowired:自動裝配通過類型、名字
如果Autowired不能唯一自動裝配上屬性,則需要通過@Qualifier(value="xxx")
@Nullable:字段標記了這個注解,說明這個字段可以為null
@Resource:自動裝配通過名字、類型
@Component:自動裝配通過名字、類型
作用域:
@Component
@Scope("prototype")
public class User {
//相當於 <property name="name" value="尹銳"></property>
@Value("尹銳")
public String name;
}
小結:
我們在使用的過程中,只需要注意一個問題:必須讓注解生效,就需要開啟注解的支持
<!--指定要掃描的包,這個包下的注解就會生效-->
<context:component-scan base-package="com.kuang"/>
<!--開啟注解的支持-->
<context:annotation-config/>
使用Java的方式配置Spring (略)
AOP
橫切關注點、切面(ASPECT)、切入點(PointCut)
SpringAOP中,通過Advice定義橫切邏輯,Spring中支持5種類型的Advice:
- 前置通知
- 后置通知
- 環繞通知
- 異常拋出通知
- 引介通知
即 Aop 在 不改變原有代碼的情況下 , 去增加新的功能 .
使用Spring實現AOP
【重點】使用AOP織入,需要導入一個依賴包!
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
在applicationContext.xml中加入對aop支持的頭文件(命名空間)
方式一:使用Spring的API接口【主要SpringAPI接口實現】 :
方式二:自定義類來實現AOP【主要是切面的定義】
方式三:使用注解實現!
package com.kuang.diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* @author yuqiliu
* @create 2020-01-03 22:03
*/
//方式三:使用注解方式實現AOP
@Aspect //標注這個類是一個切面
public class AnnotationPointCut {
@Before("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void before()
{
System.out.println("===========方法執行前==========");
}
@After("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void after()
{
System.out.println("===========方法執行后==========");
}
//在環繞增強中,我們可以給定一個參數,代表我們要獲取處理切入的點:
@Around("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("環繞前");
//執行方法
Object proceed=jp.proceed();
System.out.println("環繞后");
Signature signature = jp.getSignature();//獲得簽名
System.out.println("signature:"+signature);
System.out.println(proceed);
}
}
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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--注冊bean-->
<bean id="userService" class="com.kuang.service.UserServiceImpl"/>
<bean id="log" class="com.kuang.log.Log"/>
<bean id="afterLog" class="com.kuang.log.AfterLog"/>
<!--方式一:使用原生Spring API接口-->
<!--配置aop:需要導入aop的約束-->
<!-- <aop:config>-->
<!-- <!–切入點:expression:表達式,execution(要執行的位置! * * * * *)–>-->
<!-- <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>-->
<!-- <!–執行環繞增加!–>-->
<!-- <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>-->
<!-- <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>-->
<!-- </aop:config>-->
<!--方式二:自定義類-->
<!-- <bean id="diy" class="com.kuang.diy.DiyPointCut"/>-->
<!-- <aop:config>-->
<!-- <!–自定義切面,ref 要引用的類–>-->
<!-- <aop:aspect ref="diy">-->
<!-- <!–切入點–>-->
<!-- <aop:pointcut id="point" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>-->
<!-- <!–通知–>-->
<!-- <aop:before method="before" pointcut-ref="point"/>-->
<!-- <aop:after method="after" pointcut-ref="point"/>-->
<!-- </aop:aspect>-->
<!-- </aop:config>-->
<!--方式三-->
<bean id="annotationPointCut" class="com.kuang.diy.AnnotationPointCut"/>
<!--開啟注解支持! JDK(默認 proxy-target-class="false") cglib(proxy-target-class="true")-->
<aop:aspectj-autoproxy proxy-target-class="false"/>
</beans>