当前位置: 首页> 科技> 名企 > 上海疫情最新消息今天封城了_制作人iu_网站怎么做_制作网页用什么软件

上海疫情最新消息今天封城了_制作人iu_网站怎么做_制作网页用什么软件

时间:2025/9/6 17:02:01来源:https://blog.csdn.net/weixin_52937170/article/details/143039184 浏览次数:0次
上海疫情最新消息今天封城了_制作人iu_网站怎么做_制作网页用什么软件

前言

从spring2.0开始,spring逐步提供了各种各样的注解,到了spring2.5注解就比较完善了,到了spring3.0就是纯注解开发

使用注解进行开发可以简化开发步骤,提升开发效率,但是我们需要了解底层原理,接下来我将介绍如何使用Spring的注解来简化开发。

 注解开发定义bean

 使用注解定义bean和在xml配置文件中定义bean的效果是相同的,只不过是一种方式的不同表现,因此它们应当具有相同或相似的结构。

准备工作

第一步:创建maven项目,添加依赖

pom.xml
  <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>

第二步:接口和实体类

UserDao

public interface UserDao {public void say();
}

UserDaoImpl

@Component("userDao")
public class UserDaoImpl implements UserDao {@Overridepublic void say() {System.out.println("UserDaoImpl start...");}
}

UserService

public interface UserService {public void  say();
}

UserServiceImpl

第三步:创建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"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"></beans>	

我这个spring配置文件,包含了基本的spring配置头信息,包括了context命名空间,但是不包括aop的命名空间。 

第四步:创建测试类

APP
/*** Hello world!**/
public class App 
{public static void main( String[] args ){ApplicationContext context =new ClassPathXmlApplicationContext("spring.xml");UserDao userDao = (UserDao) context.getBean("userDao");userDa.say();}
}

使用xml定义bean

使用xml配置文件,需要定义<bean>标签

 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"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><bean id="userDaoImpl" class="org.example.dao.impl.UserDaoImpl"/></beans>	

使用注解定义bean

使用注解定义bean,本质上就是使用注解代替<bean>标签,完成bean的定义的方式

 第一步:在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"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="org.example"/></beans>	
  • 无论是xml定义bean还是注解定义bean,本质上都是spring容器启动后扫描spring的配置文件来进行bean的定义和初始化的,因此spring配置文件需要保留,但是由于定义一堆配置既麻烦又不简洁,因此出现了注解代替<bean>标签的配置方式。
  • 开启注解扫描之后,我们可以扫描spring中的注解。
  • base-package后面跟的是包名的话可以扫描当前包及其子包中是否存在注解

第二步:在要管理的实体类上加上@Component注解

 UserDaoImpl
@Component("userDao")
public class UserDaoImpl implements UserDao {@Overridepublic void say() {System.out.println("UserDaoImpl start...");}
}
  • 此时就不需要定义<bean>标签了
  • 如果使用注解不提供名字(与配置文件中bean标签的id相似),则需要使用类型进行获取对应的bean对象。

 纯注解开发

  • Spring3.0升级了纯注解开发模式,使用Java类代替配置文件,开启Spring快速开发赛道
  • 为了变成纯注解的开发模式,xml配置文件就需要里面没有其他多余代码,因此需要换一种形式表现xml配置文件中的扫描注解的标签,在java代码中主要书写的是类,因此可以用类来替代配置文件(简单理解,就是使用配置类代替配置文件,完成bean的定义)

 第一步:将spring.xml删除

其实也不用删除,不使用即可,将后缀改为bak

 

第二步:声明Java配置类

SpringConfig

@Configuration
@ComponentScan("org.example")
public class SpringConfig {}
  • @Configuration注解声明一个类,这个类的作用就和spring.xml文件的作用是一样的了
    • @Configuration注解用于设定当前类为配置类
  • @ComponentScan注解,实际上就是代替spring.xml配置文件中的开启扫描配置
    • @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式

 可以理解为使用一个Java类代替了xml配置文件,它俩起的作用是一样的。

基于注解的bean管理 

  • 在实体类上方添加@Scope注解,主要的参数有
    • singleton:单例
    • prototype:多例

 单例

@Scope("singleton")
@Component("userDao")
public class UserDaoImpl implements UserDao {@Overridepublic void say() {System.out.println("UserDaoImpl start...");}
}

使用的bean是同一个 

public class App 
{public static void main( String[] args ){ApplicationContext context =new AnnotationConfigApplicationContext(SpringConfig.class);UserDao userDao = (UserDao) context.getBean("userDao");UserDao userDao1 = (UserDao) context.getBean("userDao");System.out.println(userDao);System.out.println(userDao1);}
}

 测试效果:

地址相同,为同一个bean对象

多例

@Scope("prototype")
@Component("userDao")
public class UserDaoImpl implements UserDao {@Overridepublic void say() {System.out.println("UserDaoImpl start...");}
}

使用的bean不是同一个 

测试效果:

 地址不同,不是同一个bean对象

 bean的生命周期

自定义方法,在方法上添加@PostConstruct注解和@PreDestory注解

@Component("userService")
public class UserServiceImpl implements UserService {@Resource(name = "userDao")private UserDao userDao;@Overridepublic void say() {userDao.say();System.out.println("UserServiceImpl....");}@PostConstructpublic void  init(){System.out.println("执行初始化");}@PreDestroypublic void destroy(){System.out.println("执行销毁");}
}

测试效果:

 

只有初始化方法执行了,为什么销毁方法没有执行?

因为:JVM虚拟机执行完成后直接关闭,没有给Spring的IOC容器关闭的时机,导致销毁方法没有执行(销毁方法的时机在容器关闭时),因此需要手动设置关闭钩子或在代码执行前手动关闭Spring容器

/*** Hello world!**/
public class App 
{public static void main( String[] args ){AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(SpringConfig.class);UserDao userDao = (UserDao) context.getBean("userDao");UserDao userDao1 = (UserDao) context.getBean("userDao");System.out.println(userDao);System.out.println(userDao1);context.close();}
}

注意:  

  • close():方法属于AnnotationConfigApplicationContext和ClassPathXmlApplicationContext实现类,ApplicationContext接口中是不存在这个方法的,因此不是使用接口接收实现类的方式调用该方法。
  • close():是强制关闭IOC容器,因此必须放在要执行的代码的最后位置,因为该方法的下方不能执行任何代码
  • 除了使用close()方法关闭容器的方式外,还可以设置关闭钩子方法,它会监听JVM虚拟机的关闭的时机,自动在JVM关闭前关闭IOC容器,它的位置可以是任意的
public class App 
{public static void main( String[] args ){AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(SpringConfig.class);UserDao userDao = (UserDao) context.getBean("userDao");UserDao userDao1 = (UserDao) context.getBean("userDao");context.registerShutdownHook();System.out.println(userDao);System.out.println(userDao1);}
}

测试效果:close()和registerShutdownHook() 的效果是一样的 

 额外注意

@PostConstruct和@PreDestroy注解位于java.xml.ws.annotation包,该包是Java EE的模块一部分。J2EE已经在Java 9中被弃用,并且计划在Java 11中删除它。我使用的JDK1.8,如果大家使用的是JDK11或17以及更高版本,可能无法使用这两个注解。

解决方案:为pom.xml添加额外的依赖

    <dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version></dependency>

依赖注入

自动装配

spring注解开发,是为了加速开发,所以对原始的功能进行了阉割,如setter注入。现在使用自动装配的形式完成依赖注入

可以理解为:原先我们需要现在spring的配置文件中声明bean和bean之间的依赖关系;并且需要在要注入对象的实体类中声明set方法。现在使用注解,只需要使用@Component注解声明bean被IOC容器管理,并且使用@Autowired来注入实体类需要的对象,就可以完全替代在spring.xml的配置文件中进行一系列操作。

 创建一个Service类,需要注入Dao类

UserService

public interface UserService {public void  say();
}

UserServiceImpl

@Component("userService")
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Overridepublic void say() {userDao.say();System.out.println("UserServiceImpl....");}@PostConstructpublic void  init(){System.out.println("执行初始化");}@PreDestroypublic void destroy(){System.out.println("执行销毁");}
}

APP

/*** Hello world!**/
public class App 
{public static void main( String[] args ){AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(SpringConfig.class);UserService userService =(UserService) context.getBean("userService");userService.say();context.close();}
}

测试效果:

  • 本质上:取代了set方法,底层使用了暴力反射机制,强制给属性注入值。
  • 如果类型不唯一,可以按照名称进行注入。

@Component("userService")
public class UserServiceImpl implements UserService {@Autowired@Qualifier(value = "userDao")private UserDao userDao;@Overridepublic void say() {userDao.say();System.out.println("UserServiceImpl....");}@PostConstructpublic void  init(){System.out.println("执行初始化");}@PreDestroypublic void destroy(){System.out.println("执行销毁");}
}
  • 使用@Qualifier注解必须依赖Autowired注解,因此不能删除
  • 可以使用@Resource注解,也是按照名称进行依赖注入,但要区分两者之间的区别

@Component("userService")
public class UserServiceImpl implements UserService {@Resource(name = "userDao")private UserDao userDao;@Overridepublic void say() {userDao.say();System.out.println("UserServiceImpl....");}@PostConstructpublic void  init(){System.out.println("执行初始化");}@PreDestroypublic void destroy(){System.out.println("执行销毁");}
}
  • @Qualifier(value = "userDao"):是Spring提供的注解
  • @Resource(name = "userDao"):是JDK提供的注解

 简单类型注入

 使用@Value注解进行依赖注入

@Component("userService")
public class UserServiceImpl implements UserService {@Resource(name = "userDao")private UserDao userDao;@Value("Hello World")private String hello;@Overridepublic void say() {userDao.say();System.out.println("UserServiceImpl....");System.out.println(hello);}@PostConstructpublic void  init(){System.out.println("执行初始化");}@PreDestroypublic void destroy(){System.out.println("执行销毁");}
}

  • 简单类型的注入可以通过动态加载properties文件进行
  • 通过配置的形式加载properties文件

 

配置文件中要注意空格,因为空格也算作一个数据

@Component("userService")
@PropertySource("jdbc.properties")
public class UserServiceImpl implements UserService {@Resource(name = "userDao")private UserDao userDao;@Value("${ceshi}")private String hello;@Overridepublic void say() {userDao.say();System.out.println("UserServiceImpl....");System.out.println(hello);}@PostConstructpublic void  init(){System.out.println("执行初始化");}@PreDestroypublic void destroy(){System.out.println("执行销毁");}
}
  • @PropertySource("jdbc.properties")
    • 指定配置文件的位置,默认查找classpath路径
  • @Value注解中使用${}引入配置文件重点键值对数据
    • ${键名}

 第三方bean的管理

  • 因为引入第三方的bean,因为不能将配置写在其源代码中,因此只能编程的方式去获取。
  • 定义的方法名建议取成你想管理的bean的id名称

 接下来已管理第三方的数据源为例,演示如何使用注解的方式管理一个第三方的bean

第一步:导入数据源的依赖

我使用的是阿里巴巴的德鲁伊(druid)数据源,也可以换成其他的数据源,只是配置方式略有不同

  <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency>

 第二步:在配置类中声明第三方bean

@Configuration
@ComponentScan("org.example")
public class SpringConfig {@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName("com.mysql.cj.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/ssm_vue_demo");ds.setUsername("root");ds.setPassword("root");return ds;}
}
  • 定义一个第三方bean一般按照类型进行使用,使用名称的机会不大。
  • 获取第三方bean :就是在配置类中使用Bean注解定义一个方法,方法的返回值就是要获取的bean对象。

 测试效果:

public class App 
{public static void main( String[] args ){AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(SpringConfig.class);DataSource dataSource = context.getBean(DataSource.class);System.out.println(dataSource);}
}

 数据源和连接信息分离

需要进一步简化spring配置,因为数据库连接池信息属于jdbc配置,直接写在spring的配置中不规范,可以拆分出去

使用独立的配置类管理第三方bean

@Configuration
public class JdbcConfig {@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName("com.mysql.cj.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/ssm_vue_demo");ds.setUsername("root");ds.setPassword("root");return ds;}
}

 两种方式

方式1:

  • 将独立的配置类加入核心配置
  • 扫描式
@Configuration
//使用Component注解扫描配置类所在的包,加载对应的配置类信息,我这里扫描了全包,所有可以扫描到@Configuration注解
@ComponentScan("org.example")
public class SpringConfig {}

这种方式不推荐,因为配置类过多时,容器产生错误观察

方式2:

  • 将独立配置类加入核心配置
  • 导入式 
@Configuration
//使用@Import注解手动加入配置类到核心配置,此注解只能添加一次,多个数据请用数组格式
@Import(JdbcConfig.class)
public class SpringConfig {}

 为第三方bean注入资源

  • 简单类型注入:使用@Value注解
  • 引用类型注入:只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

注解开发总结

功能XML配置注解
定义bean

bean标签

  • id属性
  • class属性

@Component

  • @Controller
  • @Service
  • @Repository

@ComponentScan

设置依赖注入

setter注入(set方法)

  • 引用/简单

构造器注入(构造方法)

  • 引用/简单

自动装配

@Autowired

  • @Qualifier

@Value

配置第三方bean

bean标签

静态工厂、实例工厂、FactoryBean

@Bean
作用范围scope属性@Scope
生命周期

标准接口

  • init-method
  • destroy-method

@PostConstrutor

@PreDestroy

关键字:上海疫情最新消息今天封城了_制作人iu_网站怎么做_制作网页用什么软件

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: