导入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>