Spring核心知识整理(一)

Spring核心技术

DI:依赖注入
IOC:控制反转
AOP:面向切面编程   -- 思想必须掌握

1.Spring配置文件和通过工厂对象创键实例对象

命名无限制,约定有:spring-context.xml,applicationContext.xml,beans.xml
文件结构

bean标签属性讲解

id

Spring-Bean唯一标识

class

Spring-Bean全限定类名

init-method

指定Spring-Bean初始化函数 - 在 class的类里面定义的函数

destroy-method

指定Spring-Bean销毁函数

scope

指定Spring-Bean生命周期 Spring-Bean的生命周期有以下6种:

  • singleton

    单例

  • prototype

    多例

  • request

    请求域

  • session

    会话域

  • application

    上下文域

  • websocket

    会话建立连接时创建,断开连接时销毁

spring-context.xml
<!--配置实例(id:唯一标识, class="需要被创建对象的完全类名"-->
<?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/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="mc" class="MyClass"/>
</beans>      
<!--xmlns:xml namespaces,命名空间,为了避免Spring的beans标签和其他文件中的beans标签重名导致冲突-->
       <!--xmlns:xsi : 该文件使用的其他命名空间,名称为xsi,在使用其中的标签时要加入xsi:的前缀.
       xmlns冒号后面的命名空间不是固定的,可以变更。xmlns语法为:xmlns:namespace-prefix="namespaceURL"-->
       <!--xsi:schemaLocation:属性的值由一个URL引用对组成,两个URL之间以空白符分隔。第一个URL时名称空间的名字
       ,第二个URL给出模式文档的位置,模式处理器将从这个位置读取模式文档,该模式文档的目标名称空间必须与第一个URL相匹配-->
<!-- 注意:beans标签里面不能添加中文注释,否则报错 -->
<!-- 报错如下:
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 7 in XML document from class path resource [spring-context.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 13; 2 字节的 UTF-8 序列的字节 2 无效。
-->
pom.xml
<!--Spring-context:spring工厂 常用依赖-->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.3.15</version>
</dependency>
Myclass
public class MyClass {
    public void show(){
        System.out.println("HelloWorld");
    }
}
TestFactory
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestFactory {
    /**
     * 程序中的对象都交由Spring的ApplicationContext工厂进行创建
     */
    public static void main(String[] args) {
        // springcontext是spring工厂
        // 获取工厂对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");
        // 通过id创键bean对象
        MyClass m = (MyClass) ctx.getBean("mc");
        // 调用m对象的方法
        m.show();
    }
}

2.IoC(Inversion of Control) 控制反转 -- 解决接口和实现类之间的强耦合关系

Inversion of Control: 控制反转

反转了依赖关系的满足方式,由之前的自己创建依赖对象,变为由工厂推送。(变主动为被动,即反转)

解决了具有依赖关系的组件之间的强耦合,使得项目形态更加稳健

在项目中表现:在接口实现类中只定义接口对象,不创建,创建和赋值交给Spring工厂

1.项目中的强耦合问题
public class UserDaoImpl implements UserDao{...}
public class UserServiceImpl implements UserService{
	// !!!强耦合了UserDaoImpl,使得UserServiceImpl变得不稳健
	private UserDao userDao = new UserDaoImpl();
	@Override
	public User queryUser(){
		return userDao.queryUser();
	}
}
2.解决方案
// 不引用任何一个具体的组件(实现类),在需要其他组件的位置预留存取值入口(set/get)
public class UserServiceImpl implements UserService{
    // 不在耦合任何DAO实现!!!,消除不稳健因素
    private UserDao userDao;
    // 为userDao定义set/get,允许userDao属性接受spring赋值
    // Getter and Setter
    @Override
    public User queryUser(){
        return userDao.queryUser();
    }
}
<bean id="userDAO" class="com.qf.UserDaoImpl"></bean>
<!-- UserServiceImpl组件 -->
<bean id="userService" class="com.qf.UserServiceImpl">
	<!-- 由spring为userDAO赋值,值为id="userDAO"的bean -->
	<property name="userDAO" ref="userDAO"/>
</bean>

此时,如果需要更换其他UserDao实现类,则UserServiceImpl不用任何改动!

则此时的UserServiceImpl组件变得更加稳健!

3.DI(Dependency Injection)依赖注入【重点】


1. 概念

在Spring创键对象的同时,为其属性赋值,称为依赖注入。

注入分类:
1.Set注入:创建对象时,Spring工厂会通过Set方法为对象的属性赋值。
2.自建类型注入:创键次要bean作为属性,为主要bean赋值
3.构造注入:创建对象时,Spring工厂会通过构造方法为对象的属性赋值.
4.自动注入:不用再配置中指定为哪个属性赋值,及赋什么值,
由Spring自动根据某个"原则",在工厂中找一个bean,为属性注入属性值.
2. Set注入

创建对象时,Spring工厂会通过Set方法为对象的属性赋值。 -- bean对象必须由setter和getter方法

文件结构

2.0 配置文件 - pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.qf.edu</groupId>
    <artifactId>SpringLearn</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <!--Spring 工厂 依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.15</version>
        </dependency>
		<!-- 单元测试 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.15</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>*.xml</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>

            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>*</include>
                    <include>**/*</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

</project>
2.1 定义目标Bean类型 - User.java
import java.util.*;

public class User {
    private Integer id;
    private String password;
    private String sex;
    private Integer age;
    private Date bornDate;
    private String[] hobbys;
    private List<String> names;
    private Properties files;
    private Map<String,String> countries;
    private Set<String> phones;

    // getter and setter

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBornDate() {
        return bornDate;
    }

    public void setBornDate(Date bornDate) {
        this.bornDate = bornDate;
    }

    public List<String> getNames() {
        return names;
    }

    public String[] getHobbys() {
        return hobbys;
    }

    public void setNames(List<String> names) {
        this.names = names;
    }

    public Properties getFiles() {
        return files;
    }

    public void setFiles(Properties files) {
        this.files = files;
    }

    public Map<String, String> getCountries() {
        return countries;
    }

    public void setCountries(Map<String, String> countries) {
        this.countries = countries;
    }

    public Set<String> getPhones() {
        return phones;
    }

    public void setPhones(Set<String> phones) {
        this.phones = phones;
    }

    public void setHobbys(String[] hobbys) {
        this.hobbys = hobbys;
    }
}
2.2 基本类型 + 字符串类型 + 日期类型 + 容器类型 spring-context.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/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--Set injection-->
    <bean id="u1" class="User">
        <!-- base field -->
        <property name="id" value="1"/>
        <property name="password" value="123"/>
        <property name="sex" value="male"/>
        <property name="age" value="21"/>
        <property name="bornDate" value="2000/4/30"/><!-- 注意格式"/" -->
        <!--array-->
        <property name="hobbys">
            <array>
                <value>Run</value>
                <value>Sleep</value>
            </array>
        </property>
        <!--Set-->
        <property name="phones">
            <set>
                <value>123</value>
                <value>234</value>
            </set>
        </property>
        <!--List-->
        <property name="names">
            <list>
                <value>tom</value>
                <value>jack</value>
            </list>
        </property>
        <!--Map-->
        <property name="countries">
            <map>
                <entry key="CN" value="China"/>
                <entry key="US" value="America"/>
            </map>
        </property>
        <!--Properties-->
        <property name="files">
            <props>
                <prop key="first">One</prop>
                <prop key="second">Two</prop>
            </props>
        </property>
     </bean>
</beans>
2.3 测试Set注入 -- TestUser.java
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
// Set注入
public class TestUser {
    @Test
    public void t(){
        // 创键spring-context对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");
        // 通过工厂反射处user对象
        User user = (User) ctx.getBean("u1");
        System.out.println(user.getSex());
        System.out.println(user.getBornDate());
        // 字符串array
        for (String hobby : user.getHobbys()) {
            System.out.print(hobby+" ");
        }
        // map
        for (String value : user.getCountries().values()) {
            System.out.print(value+" ");
        }
    }
}
3.自建类型注入

把次要bean作为属性,为主要bean赋值

3.1 spring-context.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/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--definition type injection -->
	<!-- 次要bean ,作为主题的属性注入 Address和AddressDemo都和resource目录同一级别 -->
    <bean id="addr" class="Address">
        <property name="position" value="北京市海淀区"/>
        <property name="zipCode" value="100001"/>
    </bean>
    <!-- 主要bean ,操作的主体-->
    <bean id="ad" class="AddressDemo">
        <property name="address" ref="addr"/>
    </bean>
</beans>
3.2 pom.xml同上
3.3 Address.java
public class Address {
    private String position;
    private String zipCode;

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }

    public String getZipCode() {
        return zipCode;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }
}
3.4 AddressDemo.java
public class AddressDemo {
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}
3.4 测试
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentTest {
    @Test
    public void t(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");
        Student st = (Student) ctx.getBean("s");
        st.show();
    }
}
4.构造注入

3.构造注入:创建对象时,Spring工厂会通过构造方法为对象的属性赋值.

4.1 pom.xml同上
4.2 Bean对象 - Student.java
public class Student {
    private Integer id;
    private String name;
    private String sex;
    private Integer age;

    // Constructors

    public Student(Integer id, String name, String sex, Integer age) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    public void show(){
        System.out.println("id:"+id);
        System.out.println("name:"+name);
        System.out.println("sex:"+sex);
        System.out.println("age:"+age);
    }
}
4.3 spring-context.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/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- constuctor injection -->
    <bean id="s" class="Student">
    	<!-- name == index -->
        <constructor-arg index="0" value="1234"/>
        <constructor-arg index="1" value="tom"/>
        <constructor-arg index="2" value="male"/>
        <constructor-arg index="3" value="20"/>
    </bean>
</beans>	
4.4 测试 StudentTest
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentTest {
    @Test
    public void t(){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml");
        Student st = (Student) ctx.getBean("s");
        st.show();
    }
}
5.自动注入【了解】

不用再配置中指定为哪个属性赋值,及赋什么值。

有spring自动根据某个“原则”,在工厂中查找一个bean,为属性注入属性值

4.Bean细节


1.控制简单对象的单例、多例模式
sprint-context.xml
<bean scope="singleton|prototype"/>
<!-- 
	singleton(默认):每次调用工厂,得到的都是同一个对象
	prototype:每次调用工厂,都会创建新的对象
-->
<bean id="mc" class="MyClass" scope="singleton"/>
  • 注意:需要根据场景决定对象的单例、多例模式
  • 可以共用:Servie,DAO,SqlSessionFactory(或者所有工厂)
  • 不可共用:Connection,SqlSession,ShoppingCart

5.Spring工厂


1.饿汉式创键优势

工厂创建后,会将Spring配置文件中的所有对象都创建完成(饿汉式).

提高程序运行效率。避免多次IO,减少对象创建时间。(类似于连接池)

2.生命周期方法
  • 自定义初始化方法:添加"init-method"属性,Spring则会在创建对象之后,调用此方法.
  • 自定义销毁方法:添加"destory-method"属性,Spring则会在销毁对象之前,调用此方法
  • 销毁:工厂的close()方法被调用之后,Spring会毁掉所有已创键的单例对象
  • 分类:Singleton对象由Spring容器销毁、Prototype对象由JVM销毁
3.生命周期注解
初始化注解:@PostConstruct
销毁注解:@PreDestory
4.生命周期阶段
单例Bean:singleton
随工厂启动 创键=> 构造方法 => set方法(注入值) => init(初始化) => 构建完成 => 随工厂关闭销毁
多例Bean:prototype
被使用 创键 => 构造方法 => set方法(注入值) => init(初始化) => 构建完成 =>JVM垃圾回收销毁

6.AOP(面向切面编程) - Aspect Oriented Programming【思想重点,在spring和mvc种一般不用,但必须会思想】

AOP,即面向切面编程,利用一种称为"横切"的技术,抛开封装的对象内部,并将那些影响了多个磊的公共行为封装到一个可重用模块,并将其名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,缺位业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

0.实现原理

使用动态代理技术

  1. 基于接口的JDK官方的动态代理(优先使用)
  2. 基于子类的第三方的cglib的动态代理
  3. 基于Spring的动态代理ProxyFactory
1.AOP开发术语
  • 连接点(Joinpoint):连接点是程序类中客观存在的方法,可被Spring拦截并切入内容。
  • 切入点(Pointcut):被Spring切入连接点。
  • 通知、增强(Advice):可以为切入点添加额外功能,分为:前置通知,后置通知,异常通知,环绕通知等。
  • 目标对象:代理的目标对象
  • 引介(Introduction):一种特殊的增强,可以在运行期为动态类添加Field和Method。
  • 织入(Weaving):把通知应用到具体的类,进而创键新的代理类的过程。
  • 代理(Proxy):被AOP织入通知后,产生的结果类。
  • 切面(Aspect):由切点和通知组成,将横切逻辑织入切面所指定的连接点中。
2.作用

Spring的AOP编程即是通过动态代理类为原始类的方法添加辅助功能。

在程序运行期间,不修改源码对已有方法进行增强

3.环境搭建

引入AOP相关依赖

<!--spring aop-->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aspects</artifactId>
	<version>5.3.15</version>
</dependency>

spring-context.xml引入AOP命名空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"   <!--spring context -->
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
           
        <!--spring context -->
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
        <!--spring context -->
            
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>       
4.开发流程

定义原始类

UserService.java
package com.qf.aaron.aop.basic;
// 原始类
public interface UserService {
    public void save();
}
UserServiceImpl.java
package com.qf.aaron.aop.basic;
// 原始类
public class UserServiceImpl implements UserService{
    public void save() {
        System.out.println("save method executed...");
    }
}

定义通知类(添加额外功能)

package com.qf.aaron.aop.basic;

import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;

public class MyAdvice implements MethodBeforeAdvice {
     // 实现前置通知接口
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("before advice executed");
    }
 }

定义bean标签 - spring-context.xml

<!-- 原始对象 -->
<bean id="us" class="com.qf.aaron.aop.basic.UserServiceImpl"/>
<!-- 辅助对象 -->    
<bean id="myAdvice" class="com.qf.aaron.aop.basic.MyAdvice"/>

定义切入点(PointCut)

形成切面

<aop:config>
	<!-- 切点 -->
	<aop:pointcut id="myPonitCut" expression="execution(* save())"/>
</aop:config>	
<aop:config>
	<!-- 组装切面 -->
	<aop:advisor advice-ref="myAdvice" pointcut-ref="myPointCut"/>
</aop:config>	
5.通知类【可选】

定义通知类,达到通知效果 -- 神魔时候做什莫

前置通知:MethodBeforeAdvice
后置通知:AfterAdvice
后置通知:AfterReturningAdvice //有异常不执行,方法会因异常而结束,无返回值
异常通知:ThrowsAdvice
环绕通知:MethodInterceptor
6.通配切入点 - 切点表达式

根据表达式通配切入点

execution(
    [访问修饰符]
    [返回类型]
    [全限定类名 . ] 
    访问名
    (参数类型 | ".." , ... ) 
    [ throws 异常类型 ]
)
<!-- 匹配参数 -->
<aop:pointcut id="myPointCut" expression="execution(* *(com.qf.aaron.aop.basic.User))"/>
<!-- 匹配方法名(无参) -->
<aop:pointcut id="myPointCut" expression="execution(* save())"/>
<!-- 匹配方法名(任意参数) -->
<aop:pointcut id="myPointCut" expression="execution(* save(String s))"
<!-- 匹配返回值类型 -->
<aop:pointcut id="myPointCut" expression="execution(com.qf.aaron.aop.basic.User *(参数))"/>
<!-- 匹配类名 -->
<aop:pointcut id="myPointCut" expression="execution(* com.qf.aaron.aop.basic.UserServiceImpl.*(参数))"/>
<!-- 匹配包名 -->
<aop:pointcut id="myPointCut" expression="execution(* com.qf.aaron.aop.basic.*.*(参数))"/>
<!-- 匹配包名、以及子包名 -->
<aop:pointcut id="myPointCut" expression="execution(* com.qf.aaron.aop..*.*(参数))"/>
7.JDK和CGLIB选择
  • spring底层,包含了jdk代理和cglib代理两种动态代理生成机制
  • 基本规则是:目标业务类如果有接口则用JDK代理,没有接口则用CGLib代理
class DefaultAopProxyFactory{
	// 该方法中明确定义了 JDK代理和CGLib代理的选取规则
	// 基本规则是:目标业务中如果有接口则用JDK代理,没有接口则用CGLib代理
	public AopProxy createAopProxy(){
		...
	}
}
8.后处理器
  • spring中定义了很多后处理器;
  • 每个bean对象在创键完成之前,都会有一个后处理过程,即在加工,对bean做出相关改变和调整;
  • spring-AOP中,就有一个专门的后处理器,负责通过原始业务组件(Service),再加工得到一个代理组件。

后处理器的定义 - MyBeanPostProcessor.java
package com.qf.aaron.aop.basic;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * 定义在bean后处理器
 * 作用:在bean的创键之后,进行再加工
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    /**
     * 在bean的init方法之前执行
     * @param bean 原始的bean对象
     * @param beanName
     * @return
     * @throws BeansException
     */
    public Object postProcessBeforeInitialization(Object bean,String beanName) throws BeansException{
        System.out.println("后处理器 在init之前执行"+bean.getClass());
        return bean;
    }

    /**
     * 在bean的init方法之后执行
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    public Object postProcessAfterInitialization(Object bean,String beanName) throws BeansException{
        System.out.println("后处理器 在init之后执行~~~"+bean.getClass());
        return bean;// 此处返回的是getBean()最终的结果
    }
}
配置后处理器
<!-- 配置后处理器,将对工厂中所有的bean生命周期进行干预 -->
<bean class="com.tx.beanpostprocessor.MyBeanPostProcessor"/>
bean生命周期
构造 => 注入属性 满足依赖 => 后处理器前置过程 => 初始化 => 后处理器后置过程 => 返回 => 销毁

7. 注解开发【重点】


1.声明bean

用于替换自建类型的标签;可以更快速的声明bean

@Service 业务类专用

@Repository dao实现类专用

@Controller web层专用

@Component :IoC注解,用于描述一个类,当Spring容器扫描到此类之后,将此类的实例放到Spring容器中,默认情况下,容器bean的id为类名的大驼峰-》小驼峰

如果不想默认,显示指定为@Component("userService")

@Scope 用户控制bean的创键模式

@Service注解 -- 可以带参数,也可以不带
// @Service说明 此类是一个业务类,需要将此类纳入工厂
// @Service默认beanId 是 首字母小写的类名 eg:"userServiceImpl"
// @Service("userService") 自定义beanId为"userService"
@Service // 声明bean,且id="userServiceImpl"
@Scope("singleton") // 声明bean对象创键模式,默认单例模式;@Scope("prototype")为设置多例模式
public class UserServiceImpl implements UserService{
	...
}
@Service
@Scope
== spring-context.xml中的<bean id=首字母小写类名 class=xx scope=xx/>
2.注入(DI)

用于完成bean中属性值的注入

  • @Autowired 基于类型的自动注入
  • @Resource 基于名称自动注入
  • @Qualifier("userDao") ,限定要注入的bean的id,和@Autowired配合使用
  • @Value 注入简单类型数据(jdk8种+String)
@Service
public class UserServiceImpl implements UserService{
	@Autowired //注入类型为UserDAO的bean
	@Qualifier("userDAO2")   // 如果有多个类型为UserDao的bean,可以用此注解从中挑选一个
	private UserDAO userDAO;
	@Resource("userDAO3")
	private UserDAO userDAO1;
	@Value("100")  // 注入数字
	private Integer id;
}
3.事务控制

用于控制事务切入

  • @Transactional
  • 工厂配置中的<tx:advice...和<aop:config...可以省略!!

1655272376525

4.注解所需要的配置 spring-context.xml
<!-- 告知sping,哪些包有被注解的类、方法、属性 -->
<!-- <context:component-scan base-package=""></context:component-scan> -->
<context:component-scan base-package="com.tx"></context:component-scan>
<!-- 告知spring,@Transcational在定制事务时,基于txManager=DataSourceTransactionManager -->
<tx:annotation-driven transaction-manager="txManager"/>
5.AOP开发 -- 使用注解
使用注解


AOP使用注解配置
<!-- 添加配置如下,启用aop注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
6. 生命周期注解
@PostConstruct:生命周期注解,在此SpringBean实例化之后,执行此注解描述的方法
@PreDestory:生命周期注解,在此SpingBean销毁之前,执行此注解所描述的方法
posted @ 2022-06-15 14:13  nanfengnan  阅读(78)  评论(0编辑  收藏  举报