framework学习笔记day06---spring基础

37 篇文章 0 订阅
8 篇文章 0 订阅

bean生命周期

  • 生命周期
    • image-20211225091410868
  • bean生命周期分为四个阶段:实例化、属性赋值、初始化、销毁

BeanPostProcessor接口

  • 概述
    • 用于在对象初始化之前、初始化之后做一些处理。
  • 开发步骤
    • ①自定义类实现BeanPostProcessor接口
      • 重写方法
    • ②编写spring-core.xml
      • 将自定义类IOC到Spring容器
  • ①自定义类实现BeanPostProcessor接口
public class MyBeanPostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {//在init之前执行
        if (bean instanceof User) {
            System.out.println("init之前");
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {//在init之后执行
        if (bean instanceof User) {
            System.out.println("init之后");
        }
        return bean;
    }
}

②编写spring-core.xml

<bean class="com.atguigu.processor.MyBeanPostProcessor"></bean>

bean生命周期的练习

  • 需求
    • 利用bean生命周期自定义连接池
  • 开发步骤
    • ①自定义MyDataSource类
    • ②定义MyDataSourcePostProcessor类
    • ③编写spring-core.xml
    • ④代码测试
  • ①自定义MyDataSource类
public class MyDataSource {

    public MyDataSource(){
        System.out.println("①MyDataSource实例化");
    }

    private LinkedList<Connection> linkedList = new LinkedList<Connection>();

    private String driverClassName;//驱动


    public void setDriverClassName(String driverClassName) {
        System.out.println("②MyDataSource属性赋值");
        this.driverClassName = driverClassName;
    }

    private String jdbcUrl ;//数据库连接路径
    private String username;//账户
    private String password;//密码
    private Integer initPoolSize;//初始连接数


    private void loadDriver() throws ClassNotFoundException {
        Class.forName(driverClassName);
    }


    /**
     * 容器创建,init
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    public void init() throws ClassNotFoundException, SQLException {
        System.out.println("③②MyDataSource init");
        //加载驱动
        loadDriver();

        for (Integer i = 0; i < initPoolSize; i++) {
            Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
            linkedList.add(connection);
        }
    }

    public Connection getConnection() {
        return linkedList.removeFirst();
    }

    public void destroy(){
        System.out.println("④MyDataSource销毁");
        linkedList.clear();
    }


}

②定义MyDataSourcePostProcessor类

public class MyDataSourcePostProcessor implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof MyDataSource) {
            System.out.println("③①MyDataSource初始化之前");
            MyDataSource dataSource = (MyDataSource) bean;
            System.out.println("连接池 : " + dataSource.getInitPoolSize());//5
            dataSource.setInitPoolSize(10);
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof MyDataSource) {
            System.out.println("③③MyDataSource初始化之后");
            MyDataSource dataSource = (MyDataSource) bean;
            System.out.println("连接池 : " + dataSource.getInitPoolSize());//10
        }
        return bean;
    }
}

③编写spring-core.xml

<bean id="dataSource" class="com.atguigu.datasource.MyDataSource" init-method="init" destroy-method="destroy">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mydb1"></property>
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
    <property name="initPoolSize" value="5"></property>
</bean>

<bean class="com.atguigu.processor.MyDataSourcePostProcessor"></bean>

④代码测试

/**
 * bean生命周期练习
 */
@Test
public void test2(){
    MyDataSource dataSource = (MyDataSource) applicationContext.getBean("dataSource");
    Connection connection = dataSource.getConnection();
    try {
        PreparedStatement statement = connection.prepareStatement("select * from tb_user");
        ResultSet resultSet = statement.executeQuery();
        List<User> userList = new ArrayList<User>();
        while (resultSet.next()) {
            User user = new User();
            user.setUserName(resultSet.getString("user_name"));
            userList.add(user);
        }
        System.out.println("userList = " + userList);
    } catch (Exception e) {
        e.printStackTrace();
    }

    applicationContext.close();
    System.out.println(dataSource.getLinkedList());

}

依赖注入

  • 概述
    • dependency injection : 依赖注入
    • 是控制反转IOC的具体体现
  • 依赖注入的数据类型
    • 简单类型
    • javabean
    • 集合
  • 依赖注入的方式
    • 构造器注入
    • set方法注入
    • 注解注入

构造器注入

  • 概述
    • 通过标签,使用构造器将IOC容器中的资源设置到java程序中
  • 分类
    • ①注入简单类型
    • ②注入javabean
  • 代码实现
<bean id="user" class="com.atguigu.pojo.User">
    <!--注入简单类型-->
    <constructor-arg name="userId" value="1"></constructor-arg>
    <constructor-arg name="userName" value="zhangsan"></constructor-arg>
    <constructor-arg name="userPwd" value="12345"></constructor-arg>

    <!--注入javabean-->
    <constructor-arg name="student" ref="student"></constructor-arg>
</bean>

<bean id="student" class="com.atguigu.pojo.Student">
    <constructor-arg name="stuId" value="1"></constructor-arg>
    <constructor-arg name="stuName" value="学生1"></constructor-arg>
</bean>

注意:
构造器注入跟构造器形参名有关

set注入

  • 概述
    • 通过标签,使用set方法将IOC容器中的资源设置到java程序中
  • 代码实现
<!--set方法注入-->
<bean id="user2" class="com.atguigu.pojo.User">
    <!--注入简单类型-->
    <property name="userId" value="2"></property>
    <property name="userName" value="lisi"></property>
    <property name="userPwd" value="12345"></property>

    <!--注入javabean-->
    <property name="student" ref="student2"></property>
</bean>


<bean id="student2" class="com.atguigu.pojo.Student">
    <constructor-arg name="stuId" value="2"></constructor-arg>
    <constructor-arg name="stuName" value="学生2"></constructor-arg>
</bean>

注意:
set注入跟set方法名有关

容器注入

代码实现

public class Bean01 {

    private String[] strs;
    private List<String> strList;
    private List<Student> studentList;
    private Set<String> strSet;
    private Map<Integer,String> map;
    private Properties properties;
}
<!--构造器注入-->
<bean id="user" class="com.atguigu.pojo.User">
    <!--注入简单类型-->
    <constructor-arg name="userId" value="1"></constructor-arg>
    <constructor-arg name="userName" value="zhangsan"></constructor-arg>
    <constructor-arg name="userPwd" value="12345"></constructor-arg>

    <!--注入javabean-->
    <constructor-arg name="student" ref="student"></constructor-arg>
</bean>

<bean id="student" class="com.atguigu.pojo.Student">
    <constructor-arg name="stuId" value="1"></constructor-arg>
    <constructor-arg name="stuName" value="学生1"></constructor-arg>
</bean>


<!--set方法注入-->
<bean id="user2" class="com.atguigu.pojo.User">
    <!--注入简单类型-->
    <property name="userId" value="2"></property>
    <property name="userName" value="lisi"></property>
    <property name="userPwd" value="12345"></property>

    <!--注入javabean-->
    <property name="student" ref="student2"></property>
</bean>


<bean id="student2" class="com.atguigu.pojo.Student">
    <constructor-arg name="stuId" value="2"></constructor-arg>
    <constructor-arg name="stuName" value="学生2"></constructor-arg>
</bean>

<!--容器注入-->
<bean id="bean01" class="com.atguigu.pojo.Bean01">
    <property name="strs">
        <array>
            <value>a</value>
            <value>b</value>
            <value>c</value>
        </array>
    </property>

    <property name="strList">
        <list>
            <value>a</value>
            <value>b</value>
            <value>c</value>
        </list>
    </property>

    <property name="studentList">
        <list>
            <bean id="myStu1" class="com.atguigu.pojo.Student"></bean>
            <bean id="myStu2" class="com.atguigu.pojo.Student"></bean>
            <ref bean="student"></ref>
            <ref bean="student2"></ref>
        </list>
    </property>

    <property name="strSet">
        <set>
            <value>a</value>
            <value>b</value>
            <value>c</value>
        </set>
    </property>

    <property name="map">
        <map>
            <entry key="1" value="a"></entry>
            <entry key="2" value="b"></entry>
            <entry key="3" value="c"></entry>
        </map>
    </property>

    <property name="properties">
        <props>
            <prop key="1">a</prop>
            <prop key="2">b</prop>
            <prop key="3">c</prop>
        </props>
    </property>

</bean>

p命名空间

  • 概述
    • 为了简化依赖注入操作。
  • 语法
<bean 
      p:propertyName="值"
      p:propertyName-ref="beanId"></bean>

代码实现

<bean   id="user3"
        class="com.atguigu.pojo.User"
        p:userId="3"
        p:userName="阿磊"
        p:userPwd="250"
        p:student-ref="student3">
</bean>

<bean id="student3"
      class="com.atguigu.pojo.Student"
      p:stuId="31"
      p:stuName="阿三">
</bean>

ApplicationContext的结构- 层次结构

  • 层次结构image-20211225111930510

BeanFactory和ApplicationContext的区别

  • BeanFactory
    • 提供最基础的IOC功能
    • 使用bean时才初始化
  • ApplicationContext
    • 除了有最基础的IOC功能以外,还有AOP、事务管理、JDBCTemplate…
    • 容器初始化bean就初始化
  • 代码实现
public class ApplicationContextTest {

    @Test
    public void test1(){
        //ApplicationContext : IOC容器初始化,bean就初始化
        //ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-core.xml");
        //BeanFactory : IOC容器初始化,bean不初始化,在使用bean时才初始化
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-core.xml"));
        beanFactory.getBean("user");
    }

}

ApplicationContext的三个实现类

- ClassPathXmlApplicationContext

  • 根据类路径下的xml配置文件加载Spring容器
  • FileSystemXmlApplicationContext
    • 根据系统磁盘路径下的xml配置文件加载Spring容器
  • AnnotationConfigApplicationContext
    • 在纯注解开发中,根据配置类加载Spring容器
  • 代码实现
@Test
public void test2(){
    ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:\\Users\\qiuzhiwei\\Desktop\\spring-core.xml");
    Object user = applicationContext.getBean("user");
    System.out.println("user = " + user);
}

Spring操作数据库

  • 需求
    • Spring 整合 DbUtils,查询用户列表
  • 开发步骤
    • ①引入相关依赖
    • ②编写UserController
    • ③定义UserService及其实现子类
    • ④定义UserDao及其实现子类
    • ⑤编写spring-core.xml
  • ①引入相关依赖
<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <junit.version>4.13.2</junit.version>
    <lombok.version>1.18.22</lombok.version>
    <spring.version>5.3.13</spring.version>
    <dbutils.version>1.7</dbutils.version>
    <druid.version>1.2.8</druid.version>
    <mysql.version>5.1.48</mysql.version>
</properties>

<dependencies>

    <!--junit start-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>
    <!--junit end-->

    <!--lombok start-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </dependency>
    <!--lombok end-->

    <!--spring start-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!--spring end-->


    <!--jdbc start-->
    <dependency>
        <groupId>commons-dbutils</groupId>
        <artifactId>commons-dbutils</artifactId>
        <version>${dbutils.version}</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>${druid.version}</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
    </dependency>
    <!--jdbc end-->


</dependencies>

②编写UserController

public class UserController {

    public static void main(String[] args) throws Exception {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-core.xml");
        UserService userService = applicationContext.getBean(UserService.class);
        List<User> userList = userService.selectUserList();
        System.out.println("userList = " + userList);
    }

}

③定义UserService及其实现子类

public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public List<User> selectUserList() throws Exception {

        return userDao.selectUserList();
    }
}

④定义UserDao及其实现子类

public class UserDaoImpl implements UserDao {

    private QueryRunner queryRunner;

    public void setQueryRunner(QueryRunner queryRunner) {
        this.queryRunner = queryRunner;
    }

    @Override
    public List<User> selectUserList() throws Exception {
        return queryRunner.query(
                "select user_id userId,user_name userName, user_pwd userPwd from tb_user",
                new BeanListHandler<>(User.class)
        );
    }
}

⑤编写spring-core.xml

<!--5.1,UserServiceImpl对象放入到Spring容器,userDao成员变量进行注入-->
<bean id="userService" class="com.atguigu.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
</bean>


<!--5.2,UserDaoImpl对象放入到Spring容器,queryRunner成员变量进行注入-->
<bean id="userDao" class="com.atguigu.dao.impl.UserDaoImpl">
    <property name="queryRunner" ref="queryRunner"></property>
</bean>

<!--5.3,QueryRunner对象放入到Spring容器,ds成员变量进行注入-->
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
    <constructor-arg name="ds" ref="dataSource"></constructor-arg>
</bean>


<!--5.4,DruidDataSource对象放入到Spring容器,四个成员变量driverClassName、url、username、password进行注入-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/mydb1"></property>
    <property name="username" value="root"></property>
    <property name="password" value="root"></property>
</bean>

SpringIOC注解

说明

  • 学习基于注解的 IoC 配置,大家脑海里首先得有一个认知,即注解配置和 xml 配置要实现 的功能都是一样 的,都是要降低程序间的耦合。只是配置的形式不一样。
  • 关于实际的开发中到底使用xml还是注解,每家公司有着不同的使用习惯。所以这两种配置 方式我们都需要掌 握。

注解创建对象

  • 开发步骤
    • ①扫描注解
    • ②使用@Controller、@Service、@Repository、@Component
    • ③代码测试
  • ①扫描注解
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!--扫描注解-->
    <context:component-scan base-package="com.atguigu"></context:component-scan>

</beans>

②使用@Controller、@Service、@Repository、@Component

@Controller("userController")
public class UserController {

    public void selectUserList(){
        System.out.println("UserController selectUserList");
    }
}
@Service("userService")
public class UserServiceImpl implements UserService {
    @Override
    public void selectUserList() throws Exception {
        System.out.println("UserServiceImpl selectUserList");
    }
}
@Repository("userDao")
public class UserDaompl implements UserDao {
    @Override
    public void selectUserList() throws Exception {
        System.out.println("UserDaompl selectUserList");
    }
}
@Component("user")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {

    private Integer userId;
    private String userName;
    private String userPwd;

}

③代码测试

public class AnnotationTest {

    private ApplicationContext applicationContext ;

    @Before
    public void init(){
        applicationContext = new ClassPathXmlApplicationContext("spring-core.xml");
    }

    @Test
    public void test1() throws Exception {

        UserController userController = (UserController) applicationContext.getBean("userController");
        userController.selectUserList();

        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.selectUserList();

        UserDao userDao = (UserDao) applicationContext.getBean("userDao");
        userDao.selectUserList();

        User user = (User) applicationContext.getBean("user");
        System.out.println("user = " + user);
    }

}

**- 注意事项

  • @Controller、@Service、@Repository就是@Component

**

扫描详解

  • 方式
    • ①基本扫描
    • ②排除扫描
      • 排除@Controller
    • ③包含扫描
      • 只扫描@Controller
  • ①基本扫描
<context:component-scan base-package="com.atguigu"></context:component-scan>

②排除扫描

<context:component-scan base-package="com.atguigu">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

③包含扫描

<context:component-scan base-package="com.atguigu" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

**- 适用场景

  • 聚合项目中不同模块负责扫描不同的注解。

**

依赖注入之@Autowired

  • 概述
    • 相当于:
    • 先按照类型进行注入,再按照beanid进行注入
  • 工作流程
    • image-20211225153544235
  • 代码实现
@Controller("userController")
public class UserController {


    @Autowired
    private UserService userService2;

    public void selectUserList() throws Exception {
        System.out.println("UserController selectUserList");
        userService2.selectUserList();
    }
}
@Service("userService1")
public class UserServiceImpl implements UserService {
    @Override
    public void selectUserList() throws Exception {
        System.out.println("UserServiceImpl selectUserList");
    }
}
@Service("userService2")
public class UserServiceImpl2 implements UserService {
    @Override
    public void selectUserList() throws Exception {
        System.out.println("UserServiceImpl2 selectUserList");
    }
}

**- 注意事项

  • @Autowired不需要set方法

**

依赖注入之@Qualifier

  • 概述
    • 配合@Autowired适用,按照beanid进行注入
  • 代码实现
@Controller("userController")
public class UserController {


    @Autowired
    @Qualifier("userService2")
    private UserService userService;

    public void selectUserList() throws Exception {
        System.out.println("UserController selectUserList");
        userService.selectUserList();
    }


    public void selectUserList2() throws Exception {
        System.out.println("UserController selectUserList");
        userService.selectUserList();
    }
}

@Autowired的其他细节

  • 概述
    • @Autowired不仅仅可以作用在成员变量,也可以作用在构造器、set方法等
  • ①标记在构造器
@Component
public class UserServiceWrapper {



    private UserService userService;


    @Autowired
    public UserServiceWrapper(UserService userService2) {
        this.userService = userService1;
    }


    public UserService getUserService() {
        return userService;
    }
}

②标记在set方法

@Component
public class UserServiceWrapper {



    private UserService userService;


    @Autowired//将Spring容器中的UserService类型的bean注入到形参userService上
    @Qualifier("userService2")
    public void setUserService(UserService userService){
        this.userService = userService;
    }

    public UserService getUserService() {
        return userService;
    }
}

③佛系装配 : 一般情况下,如果装配失败抛出异常,设置佛系后,装配失败就拉到!!

@Controller("userController")
public class UserController {


    @Autowired(required = false)//佛系装配
    @Qualifier("userService3")
    private UserService userService = null;

    public void selectUserList() throws Exception {
        System.out.println("UserController selectUserList");
        userService.selectUserList();
    }

}

依赖注入之@Resource

  • 概述
    • 相当于:
    • JSR-250提供的,它是Java标准,绝大部分框架都支持。
  • 代码实现
@Controller("userController")
public class UserController {


    //①同时指定了name和type,查找name和type唯一匹配的bean
    //@Resource(name = "userService2",type = UserServiceImpl2.class)
    //②指定name,查找name唯一匹配的bean
    //@Resource(name = "userService2")
    //③指定type,查找type唯一匹配的bean
    //@Resource(type = UserServiceImpl2.class)
    //④既没有指定name,也没有指定type。先按照name查找,再按照type查找
    @Resource
    private UserServiceImpl userService;

    public void selectUserList() throws Exception {
        System.out.println("UserController selectUserList");
        userService.selectUserList();
    }

}

依赖注入之@Value

  • 概述
    • 给简单类型注入值
    • 读取properties配置文件中的值并注入
  • 代码实现
@Component("user")
public class User {


    @Value("1")
    private Integer userId ;
    @Value("浩浩")
    private String userName;
    @Value("haohao")
    private String userPwd;

}

注解整合junit

代码实现

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-core.xml")
public class UserServiceTest {

    private ApplicationContext applicationContext ;


    @Autowired
    @Qualifier("userService2")
    private UserService userService;


    @Test
    public void test1() throws Exception {
        userService.selectUserList();

    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
spring-framework-5.0.2.release-中文注释版是Spring Framework的一个版本,它是一个Java开发框架,用于构建企业级应用程序。 Spring Framework被设计为一个轻量级的、模块化的开发框架,它提供了一系列的功能和组件,使开发人员可以更加方便地构建可扩展和可维护的应用程序。这个版本中的中文注释提供了对框架内部工作原理和代码片段的解释,使开发人员可以更加容易地理解和使用Spring框架。 Spring Framework的核心特点包括依赖注入(DI)和面向切面编程(AOP)。依赖注入是指通过配置文件或注释方式将对象的依赖关系注入到目标对象中,降低了对象之间的耦合度。面向切面编程则是一种编程范式,用于处理与业务逻辑无关的横切关注点,如日志、事务等。 除了依赖注入和面向切面编程外,Spring Framework还提供了许多其他功能,如企业级服务(如事务管理、远程访问和消息传递)、Web应用程序开发(如MVC框架和REST服务)、数据访问(如对数据库的支持)和测试支持等。通过这些功能,开发人员可以更高效地开发和管理应用程序。 总的来说,spring-framework-5.0.2.release-中文注释版是一个功能强大且易于使用的框架,它在企业级应用程序开发中发挥着重要作用。通过使用这个版本,开发人员可以更容易地理解和使用Spring框架,并构建出高质量和可扩展的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值