Java-Spring

20223.1.14

Spring简介

1.Spring概览

1.1官网地址 : http://www.spring.io

1.2为了降低Java开发的复杂性,Spring采取了以下4种关键策略:

基于POJO的轻量级和最小侵入式编程

通过控制反转和依赖注入以及面向接口实现松耦合

基于切面和惯例进行声明式编程

通过切面和模板减少样板式代码

2.环境准备

2.1 jar包下载

官网jar下载地址:https://repo.spring.io/libs-release-local/org/springframework/spring/

 

 将下载的dist压缩包解压缩:

2.2 相关核心的模块说明

 Spring核心模块

Spring切面编程模块

Spring之数据访问和集成模块

Spring值Web模块

Spring测试和通信报文模块

3.常见版本号说明

 软件版本号:2.0.2.RELEASE --》X.Y.Z.RELEASE

序号格式要求说明
X 非负整数 表示主版本号(Major) 当API的兼容性变化时,X需要递增
Y 非负整数 表示次版本号(Minor),当增加功能时(不影响API的兼容性),Y需递增
Z 非负整数 表示修订号(Patch),当做Bug修复时(不影响API的兼容性),Z需要递增

 常见的版本号

版本号说明
Base 设计阶段。只有相应的设计没有具体的功能实现。
Alpha 软件的初级版本。存在较多的 bug
Bate 表示相对 alpha 有了很大的进步,消除了严重的 bug,还存在一些潜在的 bug。
Release 功能相对稳定,可以对外发布,但有时间限制
Snapshot 快照版本 尚不稳定,处于开发中
Standard 标准版本,能满足正常使用功能的版本
Lite 精简版,只含有正式版的核心功能
Enhance 增强版,功能优化的版本
RC 终测版,

Spring版本命名规则

描述方式说明含义
Snapshot 快照版 尚不稳定,处于开发中
Release 稳定版 功能相对稳定,可以对外发布,但有时间限制
GA 正式版 代表广泛可用的稳定版(General Availability)
M 里程碑版 具有一些全新的功能或是具有里程碑意义的版本
RC 终测版 即将作为正式版本发布

4. Spring的结构图

各个模块之间的相互依赖关系图

 

Spring IoC

1.IoC的概念

复制代码
1.IoC控制反转(IoC,Inversion of Control), 是一个概念,是一种思想。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。把对象的创建、初始化、 销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。

2.DI依赖注入:Dependency Injection。 依赖注入DI是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。依赖注入是目前最优秀的解耦方式。依赖注入让Spring的Bean之间以配置文件的方式组织在一起,而不是以硬编码的方式耦合在一起的。

3.IoC与DI的关系 IoC是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现方式之一是DI。 

SpringIoC 类似于 包子铺, 对象就是包子

IoC:控制反转,本质就是将对象new的过程交给了Spring容器去处理。
View Code
复制代码

2.IoC基于XML配置的实现方式

获取bean的几种方式

我们从IoC容器中获取对应的对象是通过getBean方法实现的,默认是调用的无参构造方法,如果不存在该方法就会抛出如下异常

 

根据name获取

// 可以通过bean 的name值获取
Student stu = (Student) ac.getBean("student");

根据id获取

Student stu = (Student) ac.getBean("stuId");

根据class获取

Student stu = ac.getBean(Student.class);

组合的方式查找

Student stu = ac.getBean("stuId", Student.class);

id和name的区别

id="stuId1,stuId2,stuId3"
表示bean有一个名字,就这个名字就叫stuId1,stuId2,stuId3
name="stu1,stu2,stu3"
表示bean有多个名字,分别是 stu1、stu2以及 stu3

 

View Code
复制代码
 // 创建IoC容器对象的时候就会初始化容器中管理的所有的Bean
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 去IoC容器中查找满足条件的对象
// 默认调用类型的无参构造方法
// 可以通过bean 的name值获取
Student stu = (Student) ac.getBean("student");
// 也可以通过bean的 id值获取
Student stu = (Student) ac.getBean("stuId");
// 根据要获取的对象的类型获取
Student stu = ac.getBean(Student.class);
// 根据name或者id 加class的方式获取
Student stu = ac.getBean("student2", Student.class);
Student stu = ac.getBean("stuId2", Student.class);
System.out.println(stu);
View Code
复制代码

BeanFactory和ApplicationContext的区别

BeanFactory是ApplicationContext接口的一个父接口,ApplicationContext接口定义的功能肯定要比BeanFactory接口定义的功能要强大

 

 

 通过类图结构我们能够发现BeanFactory是ApplicationContext接口的一个父接口,ApplicationContext接口定义的功能肯定要比BeanFactory接口定义的功能要强大

 

 

 

 

 

 

 

复制代码
public static void main(String[] args) {
        // 创建IoC容器对象的时候就会初始化容器中管理的所有的Bean
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("-----------");
        // 去IoC容器中查找满足条件的对象
        System.out.println(ac.getBean("stu1", Student.class));

        // 创建IoC容器对象,BeanFactory仅仅只会加载解析配置文件,并不会创建具体的实例对象
        System.out.println("*************************");
        BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        System.out.println("------------");
        // 去容器中根据条件获取对象,如果对象没有实例化那么就会创建该对象
        System.out.println(bf.getBean("stu1",Student.class));
    }
View Code
复制代码

IoC对象工厂注入

静态工厂注入:通过工厂类的普通方法获取实例对象

复制代码
package com.bobo.ioc.factory;

import com.bobo.ioc.bean.User;

/**
 * User 工厂类
 */
public class UserFactory {

    /**
     * 创建User对象
     * 方法必须是static修饰
     * @return
     */
    public static User getInstance(){
        return new User();
    }
}
View Code
复制代码
复制代码
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 静态工厂配置  -->
    <bean class="com.bobo.ioc.factory.UserFactory" factory-method="getInstance" id="user666" />
</beans>
View Code
复制代码

动态工厂注入:通过工厂类的普通方法获取实例对象

复制代码
package com.bobo.ioc.factory;

import com.bobo.ioc.bean.User;

/**
 * 动态工厂
 */
public class UserDynamicFactory {


    public User getInstance(){
        return new User();
    }
}
View Code
复制代码
复制代码
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 注册动态工厂Bean -->
    <bean class="com.bobo.ioc.factory.UserDynamicFactory" id="userDynamicFactory" />
    <!-- 从工厂对象获取User对象 -->
    <bean id="user" factory-bean="userDynamicFactory" factory-method="getInstance" />

</beans>
View Code
复制代码

3. 基于配置方式的属性注入

构造注入

第一步需要添加对应的有参构造方法,第二步在配置文件中添加对应的配置信息

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:c="http://www.springframework.org/schema/c"
       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">
    <bean class="com.keke.ioc.bean.User" >
        <constructor-arg name="id" value="666"/>
        <constructor-arg name="userName" value="keke"/>
        <constructor-arg name="gender" value="男"/>
    </bean>
</beans>
View Code
复制代码

 

 

配置的简化方式: c 名称空间

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:c="http://www.springframework.org/schema/c"
       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">
    <bean class="com.keke.ioc.bean.User" c:id="999" c:userName="lisi" c:gender="女"></bean>
</beans>
View Code
复制代码

 

 还可以通过参数的下标来传值

 

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:c="http://www.springframework.org/schema/c"
       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">
    <bean class="com.keke.ioc.bean.User" >
        <constructor-arg index="0" value="666"/>
        <constructor-arg index="1" value="keke"/>
        <constructor-arg index="2" value="男"/>
    </bean>
    <bean class="com.keke.ioc.bean.User" c:_0="123" c:_1="wanggu" c:_2="女"></bean>
</beans>
View Code
复制代码

 

设值注入

通过Bean对象的setter和getter方法来设置或获取对象的属性信息,这样一来有参构造方法就不是必须的了

复制代码
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean class="com.keke.ioc.bean.Student">
        <!--设值注入-->
        <property name="id" value="456"/>
        <property name="stuName" value="keke"/>
        <property name="className" value="K1D"/>
    </bean>

</beans>
View Code
复制代码
复制代码
package com.keke.ioc.bean;

public class Student {

    private Integer id;

    private String stuName;

    private String className;
    public Student() {
        System.out.println("student 构造器执行了 ...");
    }

    public Integer getId() {
        return id;
    }

    /**
     * 设值注入 setter方法是必须的
     * @param id
     */
    public void setId(Integer id) {
        this.id = id;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", stuName='" + stuName + '\'' +
                ", className='" + className + '\'' +
                '}';
    }
}
View Code
复制代码

 

 

简化配置:p名称空间

 

 

复制代码
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--<bean class="com.keke.ioc.bean.Student">
        &lt;!&ndash;设值注入&ndash;&gt;
        <property name="id" value="456"/>
        <property name="stuName" value="keke"/>
        <property name="className" value="K1D"/>
    </bean>-->

    <bean class="com.keke.ioc.bean.Student" p:id="123" p:stuName="keke" p:className="K1C"></bean>

</beans>
View Code
复制代码
复制代码
package com.keke.ioc;

import com.keke.ioc.bean.Student;
import com.keke.ioc.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppStart06 {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext-setter.xml");
        System.out.println(ac.getBean(Student.class));
    }
}
View Code
复制代码

 

 

对象注入

通过ref 属性来从IoC容器中获取合适的对象注入

复制代码
package com.keke.ioc.bean;

public class Cat {
    public String nickName;
    private String color;

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "nickName='" + nickName + '\'' +
                ", color='" + color + '\'' +
                '}';
    }
}
View Code
复制代码
复制代码
package com.keke.ioc.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;

public class UserBean {
    private Integer id;
    private Cat cat;
    private List<String> games;
    private Cat[] cats;
    private Map<String,Object> scores;
    private Properties properties;

    public Integer getId() {
        return id;
    }

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

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public String toString() {
        return "UserBean{" +
                "id=" + id +
                ", cat=" + cat +
                '}';
    }
}
View Code
复制代码
复制代码
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="com.keke.ioc.bean.Cat" id="cat" p:color="黑色" p:nickName="小可"></bean>
    <bean class="com.keke.ioc.bean.UserBean">
        <property name="id" value="666"></property>
        <property name="cat" ref="cat"></property>
    </bean>

</beans>
View Code
复制代码

单元测试:

复制代码
package com.keke.ioc.test;

import com.keke.ioc.bean.UserBean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Arrays;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class Test01 {
    @Test
    public void fun1(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println(ac.getBean(UserBean.class));
    }
}
View Code
复制代码

 

数组和集

Map和Properties类型注入

bean:

复制代码
package com.keke.ioc.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;

public class UserBean {
    private Integer id;
    private Cat cat;
    private List<String> games;
    private Cat[] cats;
    private Map<String,Object> scores;
    private Properties properties;

    public Integer getId() {
        return id;
    }

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

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public List<String> getGames() {
        return games;
    }

    public void setGames(List<String> games) {
        this.games = games;
    }

    public Cat[] getCats() {
        return cats;
    }

    public void setCats(Cat[] cats) {
        this.cats = cats;
    }

    public Map<String, Object> getScores() {
        return scores;
    }

    public void setScores(Map<String, Object> scores) {
        this.scores = scores;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "UserBean{" +
                "id=" + id +
                ", cat=" + cat +
                '}';
    }
}
View Code
复制代码

上下文配置:

复制代码
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--<bean class="com.keke.ioc.bean.Cat" id="cat" p:color="黑色" p:nickName="小可"></bean>
    <bean class="com.keke.ioc.bean.UserBean">
        <property name="id" value="666"></property>
        <property name="cat" ref="cat"></property>
    </bean>-->

    <!--等价的写法-->
    <bean class="com.keke.ioc.bean.UserBean">
        <property name="id" value="666"></property>
        <property name="cat">
            <bean class="com.keke.ioc.bean.Cat" p:color="黑色" p:nickName="小可"></bean>
        </property>

        <property name="games">
            <list>
                <value>LOT</value>
                <value>CHIJI</value>
                <value>WANGZHE</value>
            </list>
        </property>

        <property name="cats">
            <array>
                <bean class="com.keke.ioc.bean.Cat" p:nickName="老咪" p:color="黑色"></bean>
                <bean class="com.keke.ioc.bean.Cat" p:nickName="大咪" p:color="白色"></bean>
                <bean class="com.keke.ioc.bean.Cat" p:nickName="小老大" p:color="黑色"></bean>
            </array>
        </property>

        <property name="scores">
            <map>
                <description>用户成绩信息</description>
                <entry key="英语" value="100"></entry>
                <entry key="数学" value="98"></entry>
            </map>
        </property>

        <property name="properties">
            <props>
                <prop key="username">kezhang2</prop>
                <prop key="password">hfpayton.555</prop>
            </props>
        </property>
    </bean>
</beans>
View Code
复制代码

单元测试:

复制代码
package com.keke.ioc.test;

import com.keke.ioc.bean.UserBean;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Arrays;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class Test01 {
    @Test
    public void fun1(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println(ac.getBean(UserBean.class));
    }

    @Test
    public void fun2(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserBean bean = ac.getBean(UserBean.class);
        System.out.println(bean.getGames());
        System.out.println(Arrays.toString(bean.getCats()));
    }

    @Test
    public void fun3(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserBean user = ac.getBean(UserBean.class);
        Map<String, Object> scores = user.getScores();
        Set<String> keys = scores.keySet();
        keys.forEach(key->{
            System.out.println(key+":" + scores.get(key));
        });
        System.out.println("---------");
        Properties properties = user.getProperties();
        System.out.println(properties.get("username"));
        System.out.println(properties.get("password"));

    }
}
View Code
复制代码

结果:

4.综合小案例

三层架构+IoC实现

Bean

复制代码
package com.keke.ioc.bean;

public class User {
    private  Integer id;

    private String userName;

    public Integer getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                '}';
    }
}
View Code
复制代码

持久层

接口:

复制代码
package com.keke.ioc.dao;

import com.keke.ioc.bean.User;

/**
 * User的Dao
 */
public interface IUserDao {
    /**
     * 获取User对象
     * @return
     */
    User getUser();
}
View Code
复制代码

实现:

复制代码
package com.keke.ioc.dao.impl;

import com.keke.ioc.bean.User;
import com.keke.ioc.dao.IUserDao;

public class UserDaoImpl implements IUserDao {
    @Override
    public User getUser() {
        User user = new User();
        user.setId(666);
        user.setUserName("柯柯");
        System.out.println("持久层...");
        return user;
    }
}
View Code
复制代码

业务层

接口:

复制代码
package com.keke.ioc.service;

import com.keke.ioc.bean.User;

/**
 * User Service
 */
public interface IUserService {
    /**
     * 获取User对象
     * @return
     */
    User getUser();
}
View Code
复制代码

实现:

复制代码
package com.keke.ioc.service.impl;

import com.keke.ioc.bean.User;
import com.keke.ioc.dao.IUserDao;
import com.keke.ioc.service.IUserService;

/**
 * User 的Service实现
 */
public class UserServiceImpl implements IUserService {
    // 通过设值注入的方式做赋值  需要提供对应的setter方法
    private IUserDao dao;
    @Override
    public User getUser() {
        System.out.println("业务逻辑层...");
        return dao.getUser();
    }

    /**
     * 设值注入必须要提供的方法
     * @param dao
     */
    public void setDao(IUserDao dao) {
        this.dao = dao;
    }
}
View Code
复制代码

控制层

复制代码
package com.keke.ioc.control;

import com.keke.ioc.bean.User;
import com.keke.ioc.service.IUserService;

/**
 * 控制层
 */
public class UserController {
    private IUserService service;


    public User queryUser(){
        System.out.println("控制层...");
        return service.getUser();
    }
    public void setService(IUserService service) {
        this.service = service;
    }
}
View Code
复制代码

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 将 控制层  业务层  持久层 的三个实例添加到IoC容器中 -->
    <bean class="com.keke.ioc.dao.impl.UserDaoImpl" id="userDao"></bean>

    <bean class="com.keke.ioc.service.impl.UserServiceImpl" id="userService">
        <!-- 设值注入IUserDao实例 -->
        <property name="dao" ref="userDao"></property>
    </bean>

    <bean class="com.keke.ioc.control.UserController" id="userController">
        <!-- 设值注入 IUserService实例 -->
        <property name="service" ref="userService"></property>
    </bean>
</beans>
View Code
复制代码

测试类

复制代码
import com.keke.ioc.control.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 从IoC容器中获取UserController实例
        UserController u = ac.getBean(UserController.class);
        System.out.println(u.queryUser());
    }
}
View Code
复制代码

 

5.基于注解的形式

配置文件的实现方式在bean对象比较多的情况下,配置文件会越来越复杂,这时我们可以通过扫描加注解的方式来简化我们的操作

5.1 添加AOP支持依赖

基于注解的方式需要用到AOP的支持,所以我们需要添加AOP的依赖

5.2 添加扫描

通过context标签的component-scan属性指定我们的扫描路径

复制代码
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd
">
    <context:component-scan base-package="com.keke.ioc.bean"/>
</beans>
View Code
复制代码

5.3 @Component注解 :使bean被容器加载

复制代码
package com.keke.ioc.bean;

import org.springframework.stereotype.Component;

import javax.naming.Name;

/**
 * @Component 被该注解标识的Java会被SpringIoC容器加载
 * 默认是这样:<bean class="com.keke.ioc.bean.Cat" name="cat"><bean/>
 */
@Component(value="a111")
public class Cat {

}
View Code
复制代码

6. @Resource

和@Autowired、@Qualifier注解:替代设值注入,获取加载到IoC容器中的一个实例

复制代码
package com.keke.ioc.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * @Component 被该注解标识的Java会被SpringIoC容器加载
 */
@Component
public class UserBean {
    // 从IoC容器中获取一个Cat实例
    //@Resource(name = "cat")
    // 默认是根据类型查找的
    @Autowired
    @Qualifier("a111")
    private Cat cat;

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }
}
View Code
复制代码

测试类:

复制代码
import com.keke.ioc.bean.UserBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserBean user = ac.getBean(UserBean.class);
        System.out.println(user.getCat());
    }
}
View Code
复制代码

 

6.注解分类

注解 描述
@Component 一般用在身份不明确的组件上
@Service 一般用在Service层
@Controller 一般用在控制层
@Repository 一般用在数据库访问层

 

 

 

 

 

 

bean:

复制代码
package com.keke.ioc.bean;

public class User {
    private  Integer id;

    private String userName;

    public Integer getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                '}';
    }
}
View Code
复制代码

持久层:

接口

复制代码
package com.keke.ioc.dao;

import com.keke.ioc.bean.User;

/**
 * User的Dao
 */
public interface IUserDao {
    /**
     * 获取User对象
     * @return
     */
    User getUser();
}
View Code
复制代码

实现

复制代码
package com.keke.ioc.dao.impl;

import com.keke.ioc.bean.User;
import com.keke.ioc.dao.IUserDao;
import org.springframework.stereotype.Repository;

//@Component
@Repository
public class UserDaoImpl implements IUserDao {
    @Override
    public User getUser() {
        User user = new User();
        user.setId(666);
        user.setUserName("柯柯");
        System.out.println("持久层...");
        return user;
    }
}
View Code
复制代码

业务层:

接口

 

复制代码
package com.keke.ioc.service;

import com.keke.ioc.bean.User;

/**
 * User Service
 */
public interface IUserService {
    /**
     * 获取User对象
     * @return
     */
    User getUser();
}
View Code
复制代码

 

实现

复制代码
package com.keke.ioc.service.impl;

import com.keke.ioc.bean.User;
import com.keke.ioc.dao.IUserDao;
import com.keke.ioc.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/* User 的Service实现
         */
// @Component
@Service
// @Controller
public class UserServiceImpl implements IUserService {
    // 通过设值注入的方式做赋值  需要提供对应的setter方法
    @Autowired
    private IUserDao dao ;

    @Override
    public User getUser() {
        System.out.println("业务逻辑层....");
        return dao.getUser();
    }
}
View Code
复制代码

控制层:

复制代码
package com.keke.ioc.controller;

import com.keke.ioc.bean.User;
import com.keke.ioc.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

/**
 * 控制层
 */
//@Component
@Controller
//   @Service // 可以使用但是不推荐使用
public class UserController {
    @Autowired
    private IUserService service;

    public User queryUser(){
        System.out.println("控制层...");
        return service.getUser();
    }
}
View Code
复制代码

测试类:

复制代码
import com.keke.ioc.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {

        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 从IoC容器中获取UserController实例
        UserController u = ac.getBean(UserController.class);
        System.out.println(u.queryUser());
    }
}
View Code
复制代码

spring容器:

添加扫码方式1:

复制代码
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    <!-- 添加扫码 -->
    <context:component-scan base-package="com.keke.ioc.controller"></context:component-scan>
    <context:component-scan base-package="com.keke.ioc.service.impl"></context:component-scan>
    <context:component-scan base-package="com.keke.ioc.dao.impl"></context:component-scan>
</beans>
View Code
复制代码

测试结果:

添加扫码方式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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    <!-- 添加扫码 -->
    <context:component-scan base-package="com.keke.ioc.*" ></context:component-scan>
</beans>
View Code
复制代码

注解排查验证1:使用 @Component @Controller @Service @Repository 但是要排除掉Controller

复制代码
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    <!-- 使用 @Component @Controller @Service @Repository 但是要排除掉Controller -->
    <context:component-scan base-package="com.keke.ioc.service.impl,com.keke.ioc.dao.impl" use-default-filters="true">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
</beans>
View Code
复制代码

 注解排查验证2:不使用 @Component @Controller @Service @Repository 特殊声明使用@Controller 

复制代码
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <!-- 不使用 @Component @Controller @Service @Repository 特殊声明使用@Controller -->
    <context:component-scan base-package="com.keke.ioc.controller" use-default-filters="false">
        <!-- 包含哪个注解 -->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>


</beans>
View Code
复制代码

 

Spring AOP

AOP:面向切面编程; OOP:面向对象编程

AOP是OOP的1个有效补充

 

1.代理模式

AOP本身是基于动态代理模式实现的,掌握代理模式是学好AOP的前提条件

2.三种代理模式

静态代理:代理类在程序运行之前就已经存在。通常,代理类和目标类会实现同一接口,或派生自相同父类

动态代理--JDK代理

动态代理--CGLIB代理

 

 

Spring事务管理

posted @   船长华莱士  阅读(117)  评论(0编辑  收藏  举报
相关博文:
·  Java SE
·  Java-JDBC
·  Spring
·  Spring
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示