依赖注入,是IOC的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC容器)负责把他们组装起来。
降低程序间的耦合(依赖关系) 依赖关系的管理: 以后都交给spring来维护 在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明依赖关系的维护,就称之为依赖注入。
能注入的数据:有三类
基本类型和String。其他bean类型(在配置文件中或者注解配置过的bean)。复杂类型/集合类型。注入的方式:有三种
使用构造函数提供。使用set方法提供。使用注解提供。顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让 spring 框架来为我们注入。
说明:
使用的标签:constructor-arg标签出现的位置:bean标签的内部标签中的属性: type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型。index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始。name:用于指定给构造函数中指定名称的参数赋值。value:用于提供基本类型和String类型的数据ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象 优势: 在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。弊端: 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。 <!--默认构造器方式--> <bean id="user" class="com.kuang.pojo.User"> <property name="name" value="张三"/> </bean> <!--通过有参构造创建对象。方式一:下标赋值--> <bean id="user" class="com.kuang.pojo.User"> <constructor-arg index="0" value="jerry"/> </bean> <!--通过有参构造创建对象。方式二:类型创建,不建议使用--> <bean id="user" class="com.kuang.pojo.User"> <constructor-arg type="java.lang.String" value="jarry"/> </bean> <!--通过有参构造创建对象。方式三:通过参数名,推荐使用--> <bean id="user" class="com.kuang.pojo.User"> <constructor-arg name="name" value="jarry"/> <constructor-arg name="birthday" ref="now"/> </bean> <!-- 配置一个日期对象 --> <bean id="now" class="java.util.Date"></bean>set方法注入【常用】
涉及的标签:property出现的位置:bean标签的内部标签的属性 name:用于指定注入时所调用的set方法名称value:用于提供基本类型和String类型的数据ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象。 优势: 创建对象时没有明确的限制,可以直接使用默认构造函数。弊端: 如果有某个成员必须有值,则获取对象是有可能set方法没有执行。 <bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2"> <property name="name" value="tom" ></property> <property name="age" value="23"></property> <property name="birthday" ref="now"></property> </bean>顾名思义,就是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。
注入的有:数组,List,Set,Map,Properties,null。
Person类
public class Person { private String name; private int age; //getting、setting @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }Student类
public class Student { private String name; private Person person; private String[] arr; private List<String> myList; private Map<String,String> myMap; private Set<String> mySet; private String wife; private Properties myPro; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", person=" + person.toString() + ", arr=" + Arrays.toString(arr) + ", myList=" + myList + ", myMap=" + myMap + ", mySet=" + mySet + ", wife='" + wife + '\'' + ", myPro=" + myPro + '}'; } //getting、setting }配置文件(applicationContext.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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="person" class="com.kang.pojo.Person"> <property name="name" value="zhangsan"/> <property name="age" value="12"/> </bean> <bean id="student" class="com.kang.pojo.Student"> <!--普通值注入,value:具体属性值--> <property name="name" value="jerry"/> <!--Bean注入,ref:对象--> <property name="person" ref="person"/> <!--数组注入--> <property name="arr"> <array> <value>AAA</value> <value>BBB</value> <value>CCC</value> </array> </property> <!--List注入--> <property name="myList"> <list> <value>111</value> <value>222</value> <value>333</value> </list> </property> <!--Map注入--> <property name="myMap"> <map> <entry key="aaa" value="aaaa"></entry> <entry key="bbb" value="bbbb"></entry> <entry key="ccc" value="cccc"></entry> </map> </property> <!--Set注入--> <property name="mySet"> <set> <value>111</value> <value>222</value> <value>333</value> </set> </property> <!--null注入--> <property name="wife"> <null/> </property> <!--Properties注入--> <property name="myPro"> <props> <prop key="aaa">aaaa</prop> <prop key="bbb">bbbb</prop> <prop key="ccc">cccc</prop> </props> </property> </bean> </beans>测试类:
public class myTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.toString()); } /* Student{ name='jerry', person=Person{ name='zhangsan', age=12 }, arr=[AAA, BBB, CCC], myList=[111, 222, 333], myMap={ aaa=aaaa, bbb=bbbb, ccc=cccc }, mySet=[111, 222, 333], wife='null', myPro={ bbb=bbbb, aaa=aaaa, ccc=cccc } } */ }实体类
public class User { private String name; private int age; public User() { } public User(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } //getting、setting }配置文件
<?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" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--p命名空间注入,可以直接注入属性的值:properties--> <bean id="user" class="com.kang.pojo.User" p:name="jarry" p:age="15"/> <!--c命名空间注入,通过构造器注入:construct-args--> <bean id="user2" class="com.kang.pojo.User" c:name="张三" c:age="18"/> </beans>测试类
@Test public void test1(){ ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml"); User user = context.getBean("user", User.class); System.out.println(user); User user2 = context.getBean("user2", User.class); System.out.println(user2); }注意:p命名和c命名空间不能直接使用,需要导入xml约束。
xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"1.单例模式(Spring默认的机制)
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>2.原型模式(多例模式)
每次从容器中get的时候,都会产生一个新的对象。
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>3.其余的request、session、application,这些个只能在web开发中使用到。
在Spring中有三种装配的方式:
在xmI中显示的配置在java中显示配置隐式的自动装配bean 【重要】小结:
byname的时候,需要保证所有bean的id唯一 ,并且这个bean需要和自动注入的属性的set方法的值一致。bytype的时候, 需要保证所有bean的class唯一 ,并且这个bean需要和自动注入的属性的类型一致;全局唯一,id属性可以省略。jdk1.5支持的注解,Spring2.5支持注解
他们的作用就和在xml配置文件中的bean标签中写一个标签的作用是一样的。
要使用注解须知:
导入约束配置注解的支持 <?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:annotation-config/> </beans>作用:自动按照类型注入。只要容器中唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。
如果ioc容器中没任何bean的类型和要注入的变量类型匹配,则报错。
如果Ioc容器中多个类型匹配时:
出现位置:可以是变量上,也可以是方法上。细节:在使用注解注入时,set方法就不是必须的了。
public @interface Autowired { boolean required() default true; }科普:
@Nullable //字段标记了这个注解,说明这个字段可以为null。测试
public class Person { //如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空 @Autowired(required = false) private Cat cat; @Autowired//自动装配通过类型。名字 private Dog dog; private String name; }如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候我们可以使用@Qualifier(value=“xx”)去配合@Autowired的使用,指定一个唯一的bean对象注入。
public class Person { @Autowired @Qualifier(value = "cat22") private Cat cat; @Autowired @Qualifier(value = "dog11") private Dog dog; private String name; } <bean id="cat22" class="com.kuang.pojo.Cat"/> <bean id="dog22" class="com.kuang.pojo.Dog"/> <bean id="cat11" class="com.kuang.pojo.Cat"/> <bean id="dog11" class="com.kuang.pojo.Dog"/> <bean id="person" class="com.kuang.pojo.Person"/>作用:在照类中注入的基础之上再照名称注入。在给类成员注入时不能单独使用。但是在给方法参数注入时可以。
属性:value:用于指定注入bean的id。
作用:直接照bean的id注入。它可以独立使用。
属性:name:用于指定bean的id。
public class Person { @Resource(name = "cat22") private Cat cat; @Resource//自动装配通过名字。类型 private Dog dog; private String name; } <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="cat22" class="com.kuang.pojo.Cat"/> <bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="person" class="com.kuang.pojo.Person"/>注意:以上注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。 另外,集合类型的注入只能通过XML来实现。
小结:
@Resource和@Autowired的区别:
都是用来自动装配的,都可以放在属性字段上。@ Autowired 通过byType的方式实现,而且必须要求这个对象存在。@Resource 默认通过byname的方式实现,如果找不到名字,则通过byType实现。如果两个都找不到的情况下,就报错。@ Autowired 通过byType的方式实现,@Resource 默认通过byname的方式实现在Spring4之后,要使用注解开发,必须要保证aop的包导入了。
使用注解需要导入context约束,
<?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.kuang.pojo"/> <context:annotation-config/> </beans>作用:用于注入基本类型和String类型的数据。
属性:value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式)
SpEL的写法:${表达式}
public class User { //相当于 <property name="name" value="zhangsan"> @Value("zhangsan") private String name; public String getName() { return name; } }他们的作用就和在XML配置文件中编写一个标签实现的功能是一样的。
@Component作用:用于把当前类对象存入spring容器中。
属性: value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
等价于<bean id="user" class="com.kuang.pojo.User"/> Controller:一般用在表现层【@Controller】Service:一般用在业务层【@Service】Repository:一般用在持久层【@Repository】以上三个注解他们的作用和属性与Component是一模一样。
他们是spring框架为我们提供明确的层使用的注解,使我们的层对象更加清晰。
他们的作用就和在bean标签中使用scope属性实现的功能是一样的。
作用:用于指定bean的作用范围。
属性:value:指定范围的取值。常用取值:singleton,prototype
@Scope("prototype") public class User { private String name; public String getName() { return name; } }小结:
xml和注解:
xml 更加万能,适用于任何场合,维护简单方便。注解 不是自己类使用不了,维护相对复杂。xml与注解最佳实践:
xml用来管理bean;注解只负责完成属性的注入;我们在使用的过程中,只需要注意一个问题:必须让注解生效,就要开启注解的支持。该类是一个配置类,它的作用和bean.xml是一样的。
作用:指定当前类是一个配置类。
细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。
作用:用于通过注解指定spring在创建容器时要扫描的包。
属性:value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。
我们使用此注解就等同于在xml中配置了:
<!--告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中,而是一个名称为context名称空间和约束中--> <context:component-scan base-package="com.itheima"></context:component-scan>作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中。
属性:name:用于指定bean的id。当不写时,默认值是当前方法的名称。
细节:当我们使用注解配置方法时,如果有方法参数,spring框架会去容器中查找可用的bean对象。查找的方式和Autowired注解的作用是一样的。
作用:用于导入其他的配置类。
属性:value:用于指定其他配置类的字节码。
当我们使用Import的注解之后,Import注解的类就父配置类,而导入的都是子配置类。
作用:用于指定properties文件的位置。
属性:value:指定文件的名称和路径。
关键字:classpath,表示类路径下。
我们现在完全不适用Spring的xml配置了,全权交给Java来做。
JavaConfig是Spring的一个子项目,在Spring4后,成为一个核心功能。
User实体类
//这个注解的意思,就是说明这个类被Spring接管了,注册到容器中 @Component public class User { private String name; public String getName() { return name; } @Value("zhangsan")//属性注入值 public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; } }配置文件
@Configuration @ComponentScan("com.kuang.pojo") @Import(myConfig2.class) public class myConfig { //注册一个bean,就相当于我们之前写的一个Bean标签 //这个方法的名字,就相当于bean标签中的id属性 //这个方法的返回值,就相当于bean标签中的class属性 @Bean public User user(){ return new User();//就是返回要注入到bean的对象 } }测试类
public class myTest { public static void main(String[] args) { //如果完全是用来配置类方式去做,我们只能通过Annotation 上下文来获取容器,通过配置类的class对象加载。 ApplicationContext context = new AnnotationConfigApplicationContext(myConfig.class); User name = (User) context.getBean("user"); System.out.println(name.getName()); } }他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的。
PreDestroy作用:用于指定销毁方法。
PostConstruct作用:用于指定初始化方法。
1、应用程序的入口:main方法
2、junit单元测试中,没有main方法也能执行
junit集成了一个main方法,该方法就会判断当前测试类中哪些方法有 @Test注解,如果有junit注解就让方法执行。如果没有则不能执行。
3、junit不会管我们是否采用spring框架
在执行测试方法时,junit根本不知道我们是不是使用了spring框架,所以也就不会为我们读取配置文件/配置类创建spring核心容器。
4、由以上三点可知
当测试方法执行时,没有Ioc容器,就算写了Autowired注解,也无法实现注入。
Spring整合junit的配置:
1、导入spring整合junit的jar(坐标)
2、使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的
@Runwith(SpringJUnit4ClassRunner.class)
3、告知spring的运行器,spring和ioc创建是基于xml还是注解的,并且说明位置
@ContextConfiguration
参数说明:
locations:指定xml文件的位置,加上classpath关键字,表示在类路径下。classes:指定注解类所在地位置。注意:当我们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上。
配置文件
<?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" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd 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.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> <bean id="accountDao" class="com.atguigu.dao.impl.AccountDaoImpl"> <property name="runner" ref="runner"></property> </bean> <bean id="accountService" class="com.atguigu.service.impl.AccountServiceImpl"> <property name="accountDao" ref="accountDao"></property> </bean> <bean id="account" class="com.atguigu.domain.Account"></bean> <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"> <constructor-arg name="ds" ref="dataSource"></constructor-arg> </bean> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="url" value="jdbc:mysql://localhost:3306/eesy"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> </bean> </beans>持久层
/* 账户的持久层实现类 */ public class AccountDaoImpl implements IAccountDao { private QueryRunner runner; public void setRunner(QueryRunner runner) { this.runner = runner; } public List<Account> findAllAccount() { try{ return runner.query("select * from account",new BeanListHandler<Account>(Account.class)); }catch (Exception e) { throw new RuntimeException(e); } } public Account findAccountById(Integer accountId) { try{ return runner.query("select * from account where id = ? ",new BeanHandler<Account>(Account.class),accountId); }catch (Exception e) { throw new RuntimeException(e); } } public void saveAccount(Account account) { try{ runner.update("insert into account(name,money)values(?,?)",account.getName(),account.getMoney()); }catch (Exception e) { throw new RuntimeException(e); } } public void updateAccount(Account account) { try{ runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId()); }catch (Exception e) { throw new RuntimeException(e); } } public void deleteAccount(Integer accountId) { try{ runner.update("delete from account where id=?",accountId); }catch (Exception e) { throw new RuntimeException(e); } } }业务层
/* 账户的业务层实现类 */ public class AccountServiceImpl implements IAccountService{ private IAccountDao accountDao; public void setAccountDao(IAccountDao accountDao) { this.accountDao = accountDao; } public List<Account> findAllAccount() { return accountDao.findAllAccount(); } public Account findAccountById(Integer accountId) { return accountDao.findAccountById(accountId); } public void saveAccount(Account account) { accountDao.saveAccount(account); } public void updateAccount(Account account) { accountDao.updateAccount(account); } public void deleteAccount(Integer acccountId) { accountDao.deleteAccount(acccountId); } }测试类
public class Test1 { ApplicationContext ioc=new ClassPathXmlApplicationContext("applicationContext.xml"); @Test public void test1(){ IAccountService service= (IAccountService) ioc.getBean("accountService"); service.deleteAccount(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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd 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.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> <!--设置自动扫描的包--> <context:component-scan base-package="com.atguigu"></context:component-scan> <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"> <constructor-arg name="ds" ref="dataSource"></constructor-arg> </bean> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="url" value="jdbc:mysql://localhost:3306/eesy"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> </bean> </beans>持久层
/** * 账户的持久层实现类 */ @Repository(value = "accountDao") public class AccountDaoImpl implements IAccountDao { @Autowired private QueryRunner runner; public List<Account> findAllAccount() { try{ return runner.query("select * from account",new BeanListHandler<Account>(Account.class)); }catch (Exception e) { throw new RuntimeException(e); } } public Account findAccountById(Integer accountId) { try{ return runner.query("select * from account where id = ? ",new BeanHandler<Account>(Account.class),accountId); }catch (Exception e) { throw new RuntimeException(e); } } public void saveAccount(Account account) { try{ runner.update("insert into account(name,money)values(?,?)",account.getName(),account.getMoney()); }catch (Exception e) { throw new RuntimeException(e); } } public void updateAccount(Account account) { try{ runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId()); }catch (Exception e) { throw new RuntimeException(e); } } public void deleteAccount(Integer accountId) { try{ runner.update("delete from account where id=?",accountId); }catch (Exception e) { throw new RuntimeException(e); } } }业务层
/** * 账户的业务层实现类 */ @Service("accountService") public class AccountServiceImpl implements IAccountService{ @Autowired private IAccountDao accountDao; public List<Account> findAllAccount() { return accountDao.findAllAccount(); } public Account findAccountById(Integer accountId) { return accountDao.findAccountById(accountId); } public void saveAccount(Account account) { accountDao.saveAccount(account); } public void updateAccount(Account account) { accountDao.updateAccount(account); } public void deleteAccount(Integer acccountId) { accountDao.deleteAccount(acccountId); } }测试类
public class AccountServiceTest { @Test public void testFindAll() { //1.获取容易 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as = ac.getBean("accountService",IAccountService.class); //3.执行方法 List<Account> accounts = as.findAllAccount(); for(Account account : accounts){ System.out.println(account); } } @Test public void testFindOne() { //1.获取容易 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as = ac.getBean("accountService",IAccountService.class); //3.执行方法 Account account = as.findAccountById(1); System.out.println(account); } @Test public void testSave() { Account account = new Account(); account.setName("test"); account.setMoney(12345f); //1.获取容易 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as = ac.getBean("accountService",IAccountService.class); //3.执行方法 as.saveAccount(account); } @Test public void testUpdate() { //1.获取容易 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as = ac.getBean("accountService",IAccountService.class); //3.执行方法 Account account = as.findAccountById(4); account.setMoney(23456f); as.updateAccount(account); } @Test public void testDelete() { //1.获取容易 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as = ac.getBean("accountService",IAccountService.class); //3.执行方法 as.deleteAccount(4); } }配置类
/** * @author Guohai * @createTime 2020-07-13 17:14 */ @Configuration @ComponentScan("com.atguigu") @Import(JdbcConfig.class) @PropertySource("classpath:c3p0.properties") public class SpringConfig { }配置子类
/** * @author Guohai * @createTime 2020-07-13 17:16 */ public class JdbcConfig { @Bean(name="runner") @Scope(value = "prototype") public QueryRunner getRunner(@Qualifier("ds1") DataSource dataSource) { QueryRunner runner = new QueryRunner(dataSource); return runner; } private static DataSource dataSource = null; @Bean(name="ds1") public DataSource getDataSource() { try { Properties prop = new Properties(); InputStream is = JdbcConfig.class.getClassLoader().getResourceAsStream("jdbc.properties"); prop.load(is); dataSource = DruidDataSourceFactory.createDataSource(prop); return dataSource; } catch (Exception e) { e.printStackTrace(); } return null; } @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean(name="ds2") public DataSource getDataSource2(){ try { ComboPooledDataSource dataSource=new ComboPooledDataSource(); dataSource.setDriverClass(driver); dataSource.setJdbcUrl(url); dataSource.setUser(username); dataSource.setPassword(password); return dataSource; } catch (PropertyVetoException e) { e.printStackTrace(); } return null; } }测试类
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfiguration.class) public class AccountServiceTest { @Autowired private IAccountService as = null; @Test public void testFindAll() { //3.执行方法 List<Account> accounts = as.findAllAccount(); for(Account account : accounts){ System.out.println(account); } } @Test public void testFindOne() { //3.执行方法 Account account = as.findAccountById(1); System.out.println(account); } @Test public void testSave() { Account account = new Account(); account.setName("test anno"); account.setMoney(12345f); //3.执行方法 as.saveAccount(account); } @Test public void testUpdate() { //3.执行方法 Account account = as.findAccountById(4); account.setMoney(23456f); as.updateAccount(account); } @Test public void testDelete() { //3.执行方法 as.deleteAccount(4); } }链接: 对Spring深入的理解 | 概念的总结 链接: Spring IOC详解 链接: Spring AOP详解 链接: Spring 事务详解