framework学习笔记day05---Spring基础

本文详细介绍了Spring框架,包括其作为轻量级JavaEE框架的核心优势,如控制反转(IOC)和面向切面编程(AOP)。通过实例讲解了解耦策略,如工厂模式、反射和XML配置,并探讨了Spring的bean生命周期、多bean处理以及scope属性的应用。此外,还涵盖了Spring整合日志框架logback的配置和使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring

Spring简介

spring是分层的JavaSE及JavaEE应用于全栈的轻量级开源框架,以IoC(Inverse Of Control:控制反转/反转控制)和AOP(Aspact Oriented Programming:面向切面编程)为核心,提供了表现层SpringMVC和持久层Spring
JDBC以及业务层事务管理等众多模块的企业级应用技术,还能整合开源世界中众多著名的第三方框架和类库,逐渐成为使用最多的JavaEE企业应用开源框架。

SSH(struts2 spring hibernate)

SSM(springmvc spring mybatis)

Spring的本质是管理软件中的对象,即创建对象维护对象之间的关系

Spring的优势(特点)

  • (1)方便解耦,简化开发
  • (2)AOP编程的支持
  • (3)声明式事务的支持
  • (4)方便程序的测试
  • (5)方便集成各种优秀框架
  • 6)降低JavaEEAPI的使用难度
  • (7)Spring框架原码是经典学习范例

spring的架构

Spring 最初的目标就是要整合一切优秀资源,然后对外提供一个统一的服务。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,如下图所示:

    • image-20211224101457106

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

模块说明
核心容器Spring Core核心容器,提供Spring框架的基本功能。核心容器的主要组件是BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC)模式,将应用程序的配置和依赖性规范与实际的应用程序代码分开。
Spring ContextSpring上下文,是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
Spring AOP通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能集成到了 Spring 框架中。可以很容易地使 Spring框架管理的任何对象支持AOP。Spring AOP模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,就可以将声明性事务管理集成到应用程序中。
Spring DAOJDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
Spring ORMSpring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括JDO、Hibernate和iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
Spring WebWeb上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以Spring 框架支持与 Jakarta Struts的集成。Web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
Spring MVC框架MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

程序的耦合

耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差(降低耦合性,可以提高其独立性)。耦合性存在于各个领域,而非软件设计中独有的,但是我们只讨论软件工程中的耦合。

总结:在软件工程中,耦合指的就是指对象之间的依赖关系。对象之间的依赖程度越高,耦合度就越高。对象之间的耦合越高,维护成本越高。因此对象的设计应使类和构件之间的耦合最小。

耦合降低程序之间的依赖程度,即降低程序之间的耦合度的过程就叫做解耦

三层结构的耦合性问题

代码实现

public class UserController {

    public static void main(String[] args) throws Exception {
        UserService userService = new UserServiceImpl();
        User user = userService.selectUserById(1);
        System.out.println("user = " + user);
    }

}
public class UserServiceImpl implements UserService {
    

    public User selectUserById(int userId) throws Exception {
        UserMapper userMapper = new UserMapperImpl();
        return userMapper.selectUserById(userId);
    }
}
public class UserMapperImpl implements UserMapper {
    public User selectUserById(int userId) throws Exception {
        return new User(userId, "zhangsan", "zhangsan");
    }
}
  • 存在问题
    • ①在UserController中创建UserService对象,如果UserService类的构造器发生变化,UserController也会随着变化;
    • ②通过new方式创建对象需要导入正确的包路径,否则编译不通过就报错。
  • 解决方案
    • ①使用工厂模式;
    • ②使用反射、XML配置文件

工厂模式解耦

  • 解耦程序编写步骤:
    • 1、 创建一个Maven的Java工程
    • 2、创建持久层接口和接口实现类
    • 3、创建表现层测试程序并运行测试程序
    • 4、创建表现层测试程序(com.tedu.controller.EmpController)并运行测试程序
    • 5、通过工程+配置文件+接口(已有)方式解耦
    • 6、使用工厂获取service接口和dao接口的实例,替换使用new的方式获取接口的实例。

代码实现

public class MyApplicationContext {


    public  Object getBean(String beanName) {
        if (beanName.equals("userService")) {
            return new UserServiceImpl();
        } else if (beanName.equals("userMapper")) {
            return new UserMapperImpl();
        } else if (beanName.equals("user")) {
            return new User(1, "zhangsan", "zhangsan");
        }
        return null;
    }

}
public class UserController {

    public static void main(String[] args) throws Exception {
        UserService userService = (UserService) new MyApplicationContext()
                .getBean("userService");
        User user = userService.selectUserById(1);
        System.out.println("user = " + user);
    }

}```

```bash
public class UserServiceImpl implements UserService {


    public User selectUserById(int userId) throws Exception {

        UserMapper userMapper = (UserMapper) new MyApplicationContext()
                .getBean("userMapper");
        return userMapper.selectUserById(userId);
    }
}
public class UserMapperImpl implements UserMapper {
    public User selectUserById(int userId) throws Exception {
        return (User) new MyApplicationContext()
                .getBean("user");
    }
}

存在问题

  • if…else…if太多了,难以维护;
  • 通过new方式创建对象需要导入正确的包路径,否则编译不通过就报错。

解耦方案使用反射

  • 代码实现
public class MyApplicationContext {


    public  Object getBean(String className) {
        Object obj = null;
        try {
            obj = Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

}
public class UserController {

    public static void main(String[] args) throws Exception {
        UserService userService = (UserService) new MyApplicationContext()
                .getBean("com.atguigu.service.impl.UserServiceImpl");
        User user = userService.selectUserById(1);
        System.out.println("user = " + user);
    }

}
public class UserServiceImpl implements UserService {


    public User selectUserById(int userId) throws Exception {

        UserMapper userMapper = (UserMapper) new MyApplicationContext()
                .getBean("com.atguigu.mapper.impl.UserMapperImpl");
        return userMapper.selectUserById(userId);
    }
}
public class UserMapperImpl implements UserMapper {
    public User selectUserById(int userId) throws Exception {
        return (User) new MyApplicationContext()
                .getBean("com.atguigu.pojo.User");
    }
}

存在问题

  • 存在大量的字符串的硬编码

解耦方案使用xml配置

  • 代码实现
<?xml version="1.0" encoding="UTF-8" ?>
<beans>

    <!--UserServiceImpl对象,id=userService-->
    <bean id="userService" class="com.atguigu.service.impl.UserServiceImpl"></bean>


    <!--UserMapperImpl对象,id=userMapper-->
    <bean id="userMapper" class="com.atguigu.mapper.impl.UserMapperImpl"></bean>


    <!--User对象,id=user-->
    <bean id="user" class="com.atguigu.pojo.User"></bean>

</beans>
public class MyApplicationContext {


    private Map<String, Object> map = new HashMap<String, Object>();

    public MyApplicationContext() {
        parseXML();
    }


    /**
     * 解析xml文件
     */
    private void parseXML() {
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader
                    .read(MyApplicationContext.class.getClassLoader().getResourceAsStream("beans.xml"));
            Element rootElement = document.getRootElement();
            List<Element> beanEles = rootElement.elements("bean");
            for (Element beanEle : beanEles) {
                String id = beanEle.attribute("id").getValue();
                String className = beanEle.attributeValue("class");
                Object instance = Class.forName(className).newInstance();
                map.put(id, instance);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Object getBean(String beanName) {
        return map.get(beanName);
    }

}
public class UserController {

    public static void main(String[] args) throws Exception {
        UserService userService = (UserService) new MyApplicationContext()
                .getBean("userService");
        User user = userService.selectUserById(1);
        System.out.println("user = " + user);
    }

}
public class UserServiceImpl implements UserService {


    public User selectUserById(int userId) throws Exception {

        UserMapper userMapper = (UserMapper) new MyApplicationContext()
                .getBean("userMapper");
        return userMapper.selectUserById(userId);
    }
}
public class UserMapperImpl implements UserMapper {
    public User selectUserById(int userId) throws Exception {
        return (User) new MyApplicationContext()
                .getBean("user");
    }
}

Spring入门案例

  • 开发步骤
    - 四个核心包(依赖):Spring-core、Spring-beans、Spring-context、Spring-expression
    - ①引入依赖
    - ②编写spring-core.xml
    - ③代码测试
    - 初始化Spring容器
    ①引入Spring相关依赖
<properties>
    <spring.version>5.3.13</spring.version>
</properties>

<dependencies>

    <!--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-->
    
</dependencies>

②编写spring-core.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 http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="user" class="com.atguigu.pojo.User"></bean>
  
</beans>

③代码测试

public class IOCTest {


    @Test
    public void test1(){
        //初始化Spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-core.xml");
        User user = (User) applicationContext.getBean("user");
        System.out.println("user = " + user);
    }

}

IOC(控制反转)

IOC(inversion of )控制反转,即,把创建对象的权利交给框架。
也就是指将对象的创建、对象的存储、对象的管理交给了spring容器。(spring容器是spring中的一个核心模块,用于管理对象,底层可以理解为是一个map集合)
- -

  • image-20211224103348039

Spring使用构造器IOC对象

  • 概述
    • 标签默认使用类的无参构造器
  • 代码实现
<bean id="user" class="com.atguigu.pojo.User"></bean>

注意事项

  • 如果类没有无参构造器,报错"NoSuchMethodException: com.atguigu.pojo.User.()"

Spring使用静态工厂IOC对象

代码实现


public class Bean01 {

    private String beanName = "a";

}
public class StaticBeanFactory {

    public static Bean01 getBean(){
        return new Bean01();
    }

}
<!--Spring使用静态工厂IOC对象-->
<bean id="bean01"  factory-method="getBean" class="com.atguigu.factory.StaticBeanFactory"></bean>

Spring使用动态(实例)工厂IOC对象

代码实现

public class Bean02 {

    private String beanName = "bean02";

}
public class DynamicBeanFactory {
    public Bean02 getBean(){
        return new Bean02();
    }
}
<!--Spring使用实例工厂IOC对象-->
<bean id="bean02" factory-method="getBean" factory-bean="dynamicBeanFactory"></bean>
<bean id="dynamicBeanFactory" class="com.atguigu.factory.DynamicBeanFactory"></bean>

FactoryBean机制

  • 概述
    • 类似于静态工厂IOC对象,
    • FactoryBean是Spring提供的一种整合第三方框架的常用机制。和普通的bean不同,配置 一个FactoryBean类型的bean,在获取bean的时候得到的并不是class属性中配置的这个类 的对象,而是getObject()方法的返回值。通过这种机制,Spring可以帮我们把复杂组件创 建的详细过程和繁琐细节都屏蔽起来,只把最简洁的使用界面展示给我们。
    • Spring整合MyBatis就会使用到FactoryBean机制。
  • 开发步骤
    • ①定义类实现FactoryBean接口
      • 重写方法
    • ②将定义类IOC到Spring容器
  • ①定义类实现FactoryBean接口
public class Bean03FactoryBean implements FactoryBean<Bean03> {
    public Bean03 getObject() throws Exception {
        return new Bean03();
    }

    public Class<?> getObjectType() {
        return Bean03.class;
    }

    public boolean isSingleton() {
        return true;
    }
}

②将定义类IOC到Spring容器

<!--FactoryBean机制-->
<bean id="bean03" class="com.atguigu.factorybean.Bean03FactoryBean"></bean>

bean标签的属性

语法

<bean id="bean唯一标识" name="bean别名" class="bean全限定类名"></bean>

代码实现

<!--bean标签的属性-->
<bean id="user2" name="myUser,myUser2,myUser3" class="com.atguigu.pojo.User"></bean>

@Test
public void test5(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-core.xml");
    Object myUser3 = applicationContext.getBean("myUser3");
    System.out.println("myUser3 = " + myUser3);
}

Spring的团队开发

  • 概述
    • 在开发中,Spring的配置文件会有很多个,比如:spring-core.xml、spring-mvc.xml、spring-security.xml等等
  • ①Spring容器初始化时加载多个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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--团队开发-->
    <bean id="user1" class="com.atguigu.pojo.User"></bean>

</beans>
<?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 id="user2" class="com.atguigu.pojo.User"></bean>

</beans>
/**
 * ①Spring团队开发
 *  Spring容器初始化时加载多个xml配置文件
 */
@Test
public void test6(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring1.xml","spring2.xml");
    Object user1 = applicationContext.getBean("user1");
    System.out.println("user1 = " + user1);
    Object user2 = applicationContext.getBean("user2");
    System.out.println("user2 = " + user2);

}

②在主配置文件中import其他的配置文件(推荐)

<?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 id="user1" class="com.atguigu.pojo.User"></bean>

    <import resource="spring2.xml"></import>


</beans>
<?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 id="user2" class="com.atguigu.pojo.User"></bean>

</beans>
/**
 * ②Spring团队开发
 *  在主配置文件中import其他的配置文件
 */
@Test
public void test7(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring1.xml");
    Object user1 = applicationContext.getBean("user1");
    System.out.println("user1 = " + user1);
    Object user2 = applicationContext.getBean("user2");
    System.out.println("user2 = " + user2);
    Object user3 = applicationContext.getBean("user3");
    System.out.println("user3 = " + user3);
}
  • 注意事项
    • 如果在不同的spring配置文件中有相同的bean,遵守后配置后加载的覆盖原则。

Spring引入logback

  • 常见日志框架
    • jul : jdk自带的日志功能
    • log4j : 由Ceki Gulcu创立,后被apache收购
    • lo4j2 : apache收购log4j之后,对log4j的升级
    • logback: Ceki Gulcu看lo4j2不爽,重新搞的日志框架
  • 常见日志门面
    • slf4j : 由Ceki Gulcu创立
    • jcl : Jakarta Commons Logging,是Apache提供的一个通用日志API
  • 日志级别
    • error > warn > info > debug > trace
    • 比如:日志级别是debug,error、 warn 、 info 、 debug的信息都会打印
  • 为什么?
    • ①System.out.println()是线程安全,效率极其低下!!!
    • ②在项目开发阶段,需要将程序的运行信息打印到控制台,在项目生产阶段,不需要将程序的运行信息打印到控制台,所以就需要关闭日志打印
    • ③在项目生产阶段,需要将日志记录到日志文件、数据库中。
  • 开发步骤
    • ①引入依赖
      • slf4j、logback
    • ②编写logback.xml
    • ③使用日志记录器
  • ①引入依赖
<!--logback start-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>


<!--logback end-->
  • ②编写logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
    <!-- 指定日志输出的位置 -->
    <appender name="STDOUT"
              class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- 日志输出的格式 -->
            <!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 -->
            <pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern>
        </encoder>
    </appender>

    <!-- 设置全局日志级别。日志级别按顺序分别是:DEBUG、INFO、WARN、ERROR -->
    <!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 -->
    <root level="info">
        <!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender -->
        <appender-ref ref="STDOUT"/>
    </root>

    <logger name="com.atguigu.test.LogbackTest">
        <level value="off"/>
    </logger>



</configuration>
  • ③使用日志记录器
public class LogbackTest {

    Logger logger = LoggerFactory.getLogger(LogbackTest.class);

    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-core.xml");
        Object user = applicationContext.getBean("user");
        System.out.println("user = " + user);
        logger.debug("debug ... user : " + user);
        logger.info("info ... user : " + user);
        logger.warn("warn ... user : " + user);
        logger.error("error ... user : " + user);
    }
}

根据类型获取bean场景一

  • 需求
    • IOC容器中同类型的bean只有一个
    • IOC容器中同类型的bean有多个
  • 代码实现
<!--根据类型获取bean场景一-->
<!--同类型的bean只有一个-->
<bean id="bean04" class="com.atguigu.pojo.Bean04"></bean>
<!--同类型的bean有多个-->
<bean id="myBean04" class="com.atguigu.pojo.Bean04"></bean>
@Test
public void test8() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-core.xml");
    Bean04 bean = applicationContext.getBean(Bean04.class);
    logger.debug(bean + "");
}

总结

  • IOC容器中同类型的bean只有一个
    • 正常获取
  • IOC容器中同类型的bean有多个
NoUniqueBeanDefinitionException: No qualifying bean of type 'com.atguigu.pojo.Bean04' available: expected single matching bean but found 2: bean04,myBean04

报错

根据类型获取bean场景二

  • 需求
    • 有一个接口和一个接口的实现子类,将实现子类放入到IOC容器
    • 根据接口类型获取bean
    • 根据实现子类类型获取bean
  • 代码实现
<bean id="userService" class="com.atguigu.service.impl.UserServiceImpl"></bean>
@Test
public void test9() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-core.xml");
    //根据接口类型获取bean
    UserService bean = applicationContext.getBean(UserService.class);
    logger.debug(bean + "");
    //根据实现子类类型获取bean
    UserServiceImpl bean2 = applicationContext.getBean(UserServiceImpl.class);
    logger.debug(bean2 + "");

}
  • 总结
    • 根据接口类型获取bean
      • 正常获取
    • 根据实现子类类型获取bean
      • 正常获取

根据类型获取bean场景三

  • 需求
    • 声明一个接口,接口有多个实现子类,接口所有实现子类都放入IOC容器
    • 根据接口类型获取bean
    • 根据实现子类类型获取bean
  • 代码实现
<bean id="userService1" class="com.atguigu.service.impl.UserServiceImpl"></bean>
<bean id="userService2" class="com.atguigu.service.impl.UserServiceImpl2"></bean>
@Test
public void test10() {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-core.xml");
    //根据接口类型获取bean
    UserService bean = (UserService) applicationContext.getBean(UserService.class);
    logger.debug(bean + "");
    //根据实现子类类型获取bean
    UserService bean2 = applicationContext.getBean(UserServiceImpl2.class);
    logger.debug(bean2 + "");

}

总结

  • 根据接口类型获取bean
NoUniqueBeanDefinitionException: No qualifying bean of type 'com.atguigu.service.UserService' available: expected single matching bean but found 2: userService1,userService2
    • 报错
  • 根据实现子类类型获取bean
    • 正常获取

bean的生命周期(scope属性)

  • scope
    • singleton : 默认值,单例
    • prototype : 多例
    • request
    • session
  • 代码实现
<bean id="user" class="com.atguigu.pojo.User" scope="singleton"></bean>
public class LifeTest {

    private ApplicationContext applicationContext = null;

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

    @Test
    public void test1() {
        Object user = applicationContext.getBean("user");
        Object user2 = applicationContext.getBean("user");
        System.out.println(user == user2);
    }
}

bean的生命周期

  • 概述
    • 监听bean对象在Spring容器中的创建和销毁
  • scope=singleton
    • 创建:Spring容器初始化就创建
    • 销毁:Spring容器关闭就销毁
  • scope=prototype
    • 创建:使用时就创建
    • 销毁:交给JVM的垃圾回收机制
  • 代码实现
public class User {

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


    public void init(){//监听User对象的创建
        System.out.println("User init");
    }

    public void destroy(){//监听User对象的销毁
        System.out.println("User destroy");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值