spring 注入实现类
很多同学在进行编程学习时缺乏系统学习的资料。本页面基于spring 注入实现类内容,从基础理论到综合实战,通过实用的知识类文章,标准的编程教程,丰富的视频课程,为您在spring 注入实现类相关知识领域提供全面立体的资料补充。同时还包含 safari浏览器、samba、SAMP 的知识内容,欢迎查阅!
spring 注入实现类相关知识
-
多种方式实现Spring的Bean注入Spring的核心是控制反转(IoC)和面向切面(AOP)。Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理 。Spring工厂是用于生成Bean,对Bean进行管理。在Spring中,所有Bean的生命周期都交给Ioc容器管理。Spring中,Spring可以通过Xml形式或注解的形式来管理Bean 。下面基于注解的形式,采用多种方式实现Spring的Bean注入。具体如下:一、通过方法注入Bean1. 通过构造方法注入Bean实例代码:@Component("anotherBean1") public class AnotherBean { }@Component public class MyBean1 { private AnotherBean anotherBean1;
-
Spring DI(依赖注入)的实现方式:属性注入和构造注入依赖注入主要有两种实现方式,分别是属性 setter 注入和构造方法注入。具体介绍如下。1)属性 setter 注入指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean 的 setter 方法,即可实现基于 setter 的 DI。2)构造方法注入指 IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法实现,每个参数代表一个依赖。下面通过属性 setter 注入的案例演示 Spring 容器是如何实现依赖注入的。具体步骤如下。1. 创建 PersonService 接口在 springDemo01 项目的 com.mengma.ioc 包下创建一个名为 PersonService 的接口,该接口中包含一个 addPerson() 方法,如下所示。package com.mengma.ioc;public interface PersonService {public void add
-
Spring DI(依赖注入)的实现方式:属性注入和构造注入依赖注入主要有两种实现方式,分别是属性 setter 注入和构造方法注入。具体介绍如下。1)属性 setter 注入指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean 的 setter 方法,即可实现基于 setter 的 DI。2)构造方法注入指 IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法实现,每个参数代表一个依赖。下面通过属性 setter 注入的案例演示 Spring 容器是如何实现依赖注入的。具体步骤如下。1. 创建 PersonService 接口在 springDemo01 项目的 com.mengma.ioc 包下创建一个名为 PersonService 的接口,该接口中包含一个 addPerson() 方法,如下所示。package com.mengma.ioc;public interface PersonService {public void add
-
最详细的 Spring IOC 注入 (xml 注入 + 注解注入)@[toc](Spring IOC 容器的基本使用) 一、为什么要使用 Spring? 1.1 传统的 MVC 架构的程序 1.2 程序耦合性过高? 1.3 如何解耦? 1.4 Spring IOC 的依赖注入 二、Spring IOC 的依赖注入 2.1 使用构造函数完成依赖注入 2.1.1 标签的使用讲解 2.1.2 构造函数依赖注入的优缺点 2.1.3 使用构造函数完成依赖注入的实例 2.2 使用 setter 完成注入 2.2.1 使用 setter 完成依赖注入的功能 2.2.2 基于 setter 完成依赖注入的分析 2.3 复杂数据类型注入 2.3.1
spring 注入实现类相关课程
spring 注入实现类相关教程
- <strong>2.2 工程实现</strong> 创建工程:为了区分 xml 工程,坐标名称换成 spring_an ,其实无所谓,大家自行创建即可。导入依赖:依赖的坐标跟 xml 的工程坐标一致即可,无需导入多余的依赖。<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency></dependencies>项目代码:为了测试,在工程内部创建 UserDao 的接口和 UserDao 的实现类 UserDaoImpl。UserDao 代码如下:public interface UserDao { public void saveUser();}UserDaoImpl 的实现类代码如下:@Repositorypublic class UserDaoImpl implements UserDao { public void saveUser() { System.out.println("执行dao的保存方法"); }}注意事项: 由于我们是基于注解的方式实现对 bean 的管理,所以在实现类上面需要添加一个注解 @Repository,此注解的作用是为了 Spring 的容器启动后,需要要自动检测这些被注解的类并注册相应的 bean 实例到容器中。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/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.wyan.dao"></context:component-scan></beans>上面是本案例的配置文件,那么可以看出跟 xml 的配置文件有很大的区别:配置节点:context-component-scan 标签,这是 Spring 框架自定义的 xml 标签,通过 base-package 的属性,指明需要被自动扫描实例化的类所在位置。如上图所示,我们在 com.wyan.dao 下的类是需要扫描自动注入容器的。小细节:不是在 com.wyan.dao 下的所有类都会自动注入到容器,而是要搭配注解:比如我们的 @Repository 当然还有其余的注解,我们后面章节会详细讲解。测试类测试结果:代码解释:测试类其实跟 xml 的方式一模一样,我们本次测试的目的一样也是通过 Spring 容器管理注册的 bean 对象,只不过对象的实例化方式换成了注解,那么我们看到成功输出在控制台的测试语句,说明案例搭建完成。
- 2. 依赖注入案例 2.1概念介绍知识回顾对于依赖注入,我们在第一章第一节已经介绍过,我们回顾一下概念解释上面是我们之前对于依赖注入的一个通俗解释。那么这里再着重强调一下 IOC 控制反转与 DI 依赖注入的关系:IOC 控制反转是将对象实例化的动作交由了 Spring 框架, 它的作用是降低了程序的耦合,不需要我们手动的创建对象,但是程序的耦合性还是存在。对象中肯定会有一些其余对象的引用,那么这种引用就称呼为对象的依赖,而 DI 依赖注入其实 是 IOC 设计思想的一种表现形式。对于 这种属性依赖,我们无需手动赋予,也是讲赋值的动作交给 Spring ,那么这种操作就是 依赖注入。依赖注入方式:第一种方式是通过 xml 配置的方式实现;第二种方式是在属性或者方法上使用注解的方式实现。那么,本章节先带大家体验下 xml 方式实现依赖注入。2.2 工程实现:搭建动作介绍创建一个 maven 工程导入Spring 使用的依赖编写业务层的 Service 和持久层的 Dao java 类编写 Spring 的配置文件创建工程 导入依赖 省略可以参考之前创建过的IOC工程java 代码创建 Servcie 的接口和接口的实现类,代码如下://接口代码public interface UserService { public void deleteById(Integer id);}//实现类代码public class UserServiceImpl implements UserService { private UserDao userDao; public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void deleteById(Integer id) { System.out.println("删除的方法执行"); }}UserDao 接口和实现类代码://dao接口代码public interface UserDao {}//dao实现类代码public class UserDaoImpl implements UserDao {}代码解释: dao的接口和实现类中并没有方法,只是为了测试 作为service中的属性依赖,可以实现由 Spring 完成动态注入。重点来了:spring 的核心配置文件:配置解释:在上面的配置文件中:bean 标签是描述一个被实例化的类 而 property 则表示一类中的属性property 标签中的属性 name 一般我们写成类中的属性名称, 实际上,起决定作用的并不是属性名,下面示例再展示ref 表示当前的属性 是一个引用对象,而引用的是谁呢? ref 中的值 必须是在容器中已经实例化的一个引用对象的唯一标识。value 当前的属性可以直接赋值,所以通过 value 中,填写要赋予的数值即可测试结果代码解释可以看到 我们得到了 service 中的类属性 Userdao 的实例,并且也 得到了 字符串属性 userName的值 zs2.3 property注入属性的解释刚刚我们在上面的示例中 展示了xml依赖属性的注入,也是比较好理解。这里我们强调一下使用的注意事项:如果是 property 属性标签实现属性注入,那么类中必须由配置在 property 标签中 name 属性的 set 方法下面我们测试一下set方法的改变:先讲 service 中 dao 的 set 方法改造如下:public void setDao(UserDao userDao) { System.out.println("执行了set方法 给dao属性赋值"); this.userDao = userDao;}这时候代码中的set方法变成了 setDao 配置文件不变,依然是<property name="userDao" ref="userDao"></property>我们看看会产生什么问题Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'userDao' of bean class [com.wyan.service.UserServiceImpl]: Bean property 'userDao' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? at org.springframework.beans.BeanWrapperImpl.createNotWritablePropertyException(BeanWrapperImpl.java:247) at org.springframework.beans.AbstractNestablePropertyAccessor.processLocalProperty(AbstractNestablePropertyAccessor.java:426) at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:278) at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:266) at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:97) at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:77) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1646)可以看到异常的堆栈信息 无效的 userDao 属性, userDao 不可以 或者 没有有效的 setter 方法提供。更改xml文件中的 property 标签的 name 属性 为 dao<property name="dao" ref="userDao"></property>测试结果如下:所以我们说 property 中的 name 属性不一定要跟 Java类中的属性名保持一致 而是必须跟 setter 方法的名称一致
- 2.3 注解注入规则 刚刚通过三个注解都可以完成了 bean 的实例化注入,通过测试代码也获取到了容器中的三个对象实例,那么这里不知道大家是否发现一个问题:我们知道,Spring 这个容器本质是个 map 集合来存储实例化后的对象。既然是个 map 集合,就应该对应的有 key 和 value。我们都知道 value 肯定是实例化后的 bean ,那么 key 是什么呢?注入规则:1. 四种注解都支持 value 的属性作为自定义的 bean id ;2. 如果 value 属性没有指定,那么默认以类的简单名称(类名首字母小写)作为 bean 对象的 id。所以我们可以看到:当我们只使用注解没有自定义 id 的时候可以通过,每个类的首字母小写来获取对象实例,那么如果有了自定义的 id,上述代码是否继续可用呢?自定义 id 获取实例:改造类上面的注解,设置自定的 id,更改的注解如下:@Controll("uc")@Service("us")@Repository("ud")测试结果:测试结果:为了区分测试结果,我在测试代码中,只修改了 controller 的获取方式,将 id 改成了 uc 。service 和 dao 并没有修改。从控制台打印可以看到,只有 controller 对象可以成功获取,service 和 dao 都失败了,因为我们已经使用了自定义的 id,所以容器中没有默认的以类名作为 id 的 bean 对象实例。
- 3. Spring Boot 实现 我们就针对上面的场景,使用 Spring Boot ,结合 RabbitMQ 来具体实现下水果采购、配送的管理。
- 2.2 代码实现 1. 创建 maven 工程:pom 文件的 jar 包坐标如下:<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency></dependencies>2. 连接数据库的工具类:@Componentpublic class ConnectionUtils { private ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); @Autowired private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } /** * 获取当前线程上的连接 * @return */ public Connection getThreadConnection() { try{ //1.先从ThreadLocal上获取 Connection conn = tl.get(); //2.判断当前线程上是否有连接 if (conn == null) { //3.从数据源中获取一个连接,并且存入ThreadLocal中 conn = dataSource.getConnection(); conn.setAutoCommit(false); tl.set(conn); } //4.返回当前线程上的连接 return conn; }catch (Exception e){ throw new RuntimeException(e); } } /** * 把连接和线程解绑 */ public void removeConnection(){ tl.remove(); }}3. 实体类 Account:public class Account implements Serializable { //数据id private Integer id; //账号编码 private String accountNum; //账号金额 private Float money; //省略get 和set 方法}4. 持久层 dao 和 dao 的 实现类://dao的接口public interface IAccountDao { /** * 更新 * @param account */ void updateAccount(Account account); /** * 根据编号查询账户 */ Account findAccountByNum(String accountNum);}//dao的实现类@Repositorypublic class AccountDaoImpl implements IAccountDao { //dbutil的查询工具类 @Autowired private QueryRunner runner; //连接的工具类 @Autowired private ConnectionUtils connectionUtils; public void setRunner(QueryRunner runner) { this.runner = runner; } public void setConnectionUtils(ConnectionUtils connectionUtils) { this.connectionUtils = connectionUtils; } //修改账号 public void updateAccount(Account account) { try{ runner.update(connectionUtils.getThreadConnection(),"update account set accountNum=?,money=? where id=?",account.getAccountNum(),account.getMoney(),account.getId()); }catch (Exception e) { throw new RuntimeException(e); } } //根据账号查询 public Account findAccountByNum(String accountNum) { try{ List<Account> accounts = runner.query(connectionUtils.getThreadConnection(),"select * from account where accountNum = ? ",new BeanListHandler<Account>(Account.class),accountNum); if(accounts == null || accounts.size() == 0){ return null; } if(accounts.size() > 1){ throw new RuntimeException("结果集不唯一,数据有问题"); } return accounts.get(0); }catch (Exception e) { throw new RuntimeException(e); } }}代码解释: AccountDaoImpl 类上面的注解 @Repository 表示使用注解实例化此类,并交给 Spring 的容器管理。5. 业务类 Service 和 Service 的实现类://业务接口public interface IAccountService { /** * 转账 * @param sourceAccount 转出账户名称 * @param targetAccount 转入账户名称 * @param money 转账金额 */ void transfer(String sourceAccount, String targetAccount, Integer money);}//业务实现类@Servicepublic class AccountServiceImpl implements IAccountService { @Autowired private IAccountDao accountDao; public void setAccountDao(IAccountDao accountDao) { this.accountDao = accountDao; } public void transfer(String sourceAccount, String targetAccount, Integer money) { Account source = accountDao.findAccountByNum(sourceAccount); Account target = accountDao.findAccountByNum(targetAccount); source.setMoney(source.getMoney()-money); target.setMoney(target.getMoney()+money); accountDao.updateAccount(source); accountDao.updateAccount(target); System.out.println("转账完毕"); }}代码解释:AccountServiceImpl 类上面的注解 @Service 表示使用注解实例化此类,并交给 Spring 的容器管理。6. 事务管理器类@Component@Aspectpublic class TransactionManager { @Autowired private ConnectionUtils connectionUtils; public void setConnectionUtils(ConnectionUtils connectionUtils) { this.connectionUtils = connectionUtils; } @Pointcut("execution(* com.offcn.service.impl.*.*(..))") private void pt1() {} /** * 开启事务 */ @Before("pt1()") public void beginTransaction(){ try { System.out.println("开启事务"); connectionUtils.getThreadConnection().setAutoCommit(false); }catch (Exception e){ e.printStackTrace(); } } /** * 提交事务 */ @AfterReturning("pt1()") public void commit(){ try { System.out.println("提交事务"); connectionUtils.getThreadConnection().commit(); }catch (Exception e){ e.printStackTrace(); } } /** * 回滚事务 */ @AfterThrowing("pt1()") public void rollback(){ try { System.out.println("回滚事务"); connectionUtils.getThreadConnection().rollback(); }catch (Exception e){ e.printStackTrace(); } } /** * 释放连接 */ @After("pt1()") public void release(){ try { System.out.println("释放连接"); connectionUtils.getThreadConnection().close();//还回连接池中 connectionUtils.removeConnection(); }catch (Exception e){ e.printStackTrace(); } }}代码解释:此类通过注解 @Componet 实例化,并且交由 Spring 容器管理,@Aspect 表明它是一个切面类。而下面的注解 @Pointcut 和其余的方法上的各个通知注解,在上面也已经介绍过,这里不做赘述了。主要专注点在于每个注解的通知方法内部引入切入点的表达式方式。7. 配置文件:<?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:aop="http://www.springframework.org/schema/aop" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--配置QueryRunner--> <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"></bean> <!-- 配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!--连接数据库的必备信息--> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/transmoney"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> </bean> <!-- 注解扫描工程下的包路径--> <context:component-scan base-package="com.offcn"></context:component-scan> <!-- 注解代理模式 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>配置文件说明:dataSource: 采用 c3p0 数据源,大家一定要注意数据库的名称与账号名和密码;queryRunner: dbutils 第三方框架提供用于执行 sql 语句,操作数据库的一个工具类;context:component-scan: 此注解表示注解方式初始化容器扫描的包路径;aop:aspectj-autoproxy: 此注解表示开启代理模式8. 测试类代码@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:applicationContext.xml")public class AccountServiceTest { @Autowired private IAccountService accountService; @Test public void testTransfer(){ accountService.transfer("622200009999","622200001111",100); }}测试结果:执行代码后结果:可以看到,我们通过注解方式配置 Spring 的 AOP 相关配置,同样实现了对于数据的操作。
- 4.2 注入 OutputStream 在控制器的方法中注入 OutputStream 对象,只需要在方法中添加参数声明。如下实例:可使用 OutputStream 对象读取指定文件中的内容后直接响应给浏览器。@RequestMapping(value = "/testApi05")public void hello(OutputStream outputStream) throws IOException { Resource res = new ClassPathResource("/test.txt"); FileCopyUtils.copy(res.getInputStream(), outputStream);}test.txt 文件的内容是”this is a test’。文件直接放在项目的 src/main/java 目录下。在浏览器中输入请求路径 http://localhost:8888/sm-demo/testApi05 。你将在浏览器中看到:有句话叫做 “条条道路通罗马”,用在 Spring MVC 中真的是合适,依靠 Spring 强大的注入功能,只要原生开发中能有的对象基本上都能注入进去。
spring 注入实现类相关搜索
-
s line
safari浏览器
samba
SAMP
samplerate
sandbox
sanitize
saper
sas
sass
save
smarty模板
smil
smtp
snapshot
snd
snmptrap
soap
soapclient
soap协议