精华内容
下载资源
问答
  • IOC理论推导

    2020-12-28 14:22:47
    没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓的控制反转就是:获得依赖对象的方式反转...

    IOC本质
    控制反转IOC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓的控制反转就是:获得依赖对象的方式反转了。

    采用XML方式配置Bean的定义信息是和实现分离的,而采用的注释的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

    控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式,在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入

    展开全文
  • Spring 基于注解的Ioc

    2020-06-24 16:34:04
    基于完全注解的CURD4.1 创建表4.2 创建工程4.3 创建实体类4.4 持久层4.5 业务层4.6 配置类4.7 单元测试 1. 基于注解的Ioc配置 Spring基于XML文件配置的形式为: <bean id="accountService" class="dyliang....


    1. 基于注解的Ioc配置

    Spring基于XML文件配置的形式为:

    <bean id="accountService" class="dyliang.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
    
    <bean id="accountDao" class="dyliang.dao.impl.IAccountDaoImpl">
        <property name="runner" ref="runner"></property>
    </bean>
    

    accountService和accountDao相对应的类实现代码为:

    public class IAccountDaoImpl implements IAccountDao {
    
        @Autowired
        private QueryRunner runner;
    
        public List<Account> findAll() {
            try {
                return runner.query("select * from account", new BeanListHandler<Account>(Account.class));
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    
        public Account findById(Integer id) {
            try {
                return runner.query("select * from account where id=?", new BeanHandler<Account>(Account.class), id);
            }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 id) {
            try {
                runner.update("delete from account where id=?",id);
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    
    
    public class AccountServiceImpl implements IAccountService {
    
        @Autowired
        private IAccountDao accountDao;
    
        public List<Account> findAll() {
            return accountDao.findAll();
        }
    
        public Account findById(Integer id) {
            return accountDao.findById(id);
        }
    
        public void saveAccount(Account account) {
            accountDao.saveAccount(account);
        }
    
        public void updateAccount(Account account) {
            accountDao.updateAccount(account);
        }
    
        public void deleteAccount(Integer id) {
            accountDao.deleteAccount(id);
        }
    }
    
    

    spring中提供了注解@Component来配置资源的管理,对于

    <bean id="accountService" class="dyliang.service.impl.AccountServiceImpl"></bean>
    

    的功能相同实现只需要在对应的类上使用注解@Component,如下所示:

    @Component
    public class AccountServiceImpl implements IAccountService {
        private IAccountDao accountDao;
    
        public void setAccountDao(IAccountDao accountDao) {
            this.accountDao = accountDao;
        }
    
        public List<Account> findAll() {
            return accountDao.findAll();
    }
    

    使用了注解@Component后,虽然在bean.xml文件中不需要配置<bean>,但需要配置<context:component-scan>来告诉spring在创建Ioc容器时应该扫描哪些包,即使用@Component注解的类所在的包

    <context:component-scan base-package="dyliang"></context:component-scan>
    

    同时导入约束时需要多导入一个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
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    

    最后编写测试类来执行单元测试

    public class AccountTest {
    
        @Test
        public void testFindAll() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            IAccountService as = ac.getBean("accountService", IAccountService.class);
            List<Account> accounts = as.findAll();
            for (Account account : accounts) {
                System.out.println(account);
            }
        }
    
        @Test
        public void testFindOne() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            IAccountService as = ac.getBean("accountService",IAccountService.class);
            Account account = as.findById(1);
            System.out.println(account);
        }
    
        @Test
        public void testSave() {
            Account account = new Account();
            account.setName("test");
            account.setMoney(12345f);
    
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            IAccountService as = ac.getBean("accountService",IAccountService.class);
            as.saveAccount(account);
        }
    
        @Test
        public void testUpdate() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            IAccountService as = ac.getBean("accountService",IAccountService.class);
            Account account = as.findById(4);
            account.setMoney(23456f);
            as.updateAccount(account);
        }
    
        @Test
        public void testDelete() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            IAccountService as = ac.getBean("accountService",IAccountService.class);
            as.deleteAccount(4);
        }
    }
    
    

    2. 常用注解

    2.1 创建对象

    • @Component:把资源让spring来管理,相当于在xml中配置一个bean。
      • 属性value:指定bean的id,如果不指定value属性,默认bean的id是当前类首字母小写的类名

    @Controller @Service @Repository和@Component的作用相同,但是语义更加的明确,显式的指明了注解适合使用的地方。同样可使用value属性来指定具体的名字,因为只有value,所以也可以省略不写。

    • @Controller:一般用于表现层

    • @Service:一般用于业务层

      @Service("accountService")
      public class AccountServiceImpl implements IAccountService {}
      
    • @Repository:一般用于持久层

      @Repository("accountDao")
      public class IAccountDaoImpl implements IAccountDao {}
      

    2.2 注入数据

    • @Autowired:自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型。当有多个类型匹配时,使用要注入的对象变量名称作为bean的id,在spring容器查找,找到了可以注入成功;找不到就报错。使用方式如下:

      @Service("accountService")
      public class AccountServiceImpl implements IAccountService {
      
          @Autowired
          private IAccountDao accountDao;
      }
      

      当使用时,程序就会在Ioc容器中中找id为accountDao,对应的class为IAccountDao的对象。如果有,则自动注入,否则报错。

    • @Qualifier:在自动按照类型注入的基础之上,再按照Bean的id注入。它在给字段注入时不能独立使用,必须和@Autowired一起使用;但是给方法参数注入时,可以独立使用

      • 属性value::指定bean的id
    • @Resource:直接按照Bean的id注入,它也能注入其他bean类型

      • 属性name:指定bean的id
    • @Value:注入基本数据类型和String类型数据的值

      • 属性value:用于指定值

    2.3 改变作用范围

    • @Scope:指定bean的作用范围
      • 属性value:指定范围的值,取值:singleton、 prototype、 request 、session 、globalsession

    2.4 生命周期

    • @PostConstruct : 用于指定初始化方法
    • @PreDestroy : 用于指定销毁方法

    2.5 配置

    • @Configuration:用于指定当前类是一个spring配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration注解的类.class)

      • 属性value:用于指定配置类的字节码
    • @ComponentScan:用于指定spring在初始化容器时要扫描的包。作用和在spring的xml配置文件中的<context:component-scan base-package="dyliang"/>一样

      • 属性basePackages:用于指定要扫描的包
    • @Bean:该注解只能写在方法上,表明使用此方法创建一个对象,并且放入spring容器

      • 属性name:给当前@Bean注解方法创建的对象指定一个名称(即bean的id)
    • @PropertySource:用于加载.properties文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到properties配置文件中,就可以使用此注解指定properties配置文件的位置

      • 属性value[]:用于指定properties文件位置。如果是在类路径下,需要写上classpath:
    • @Import:用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration注解

      • 属性 value[]:用于指定其他配置类的字节码
    public class JdbcConfig {
    
        @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="runner")
        @Scope("prototype")
        public QueryRunner createQueryRunner(@Qualifier("ds") DataSource dataSource){
            return new QueryRunner(dataSource);
        }
    
        @Bean(name="ds")
        public DataSource createDataSource(){
            try {
                ComboPooledDataSource ds = new ComboPooledDataSource();
                ds.setDriverClass(driver);
                ds.setJdbcUrl(url);
                ds.setUser(username);
                ds.setPassword(password);
                return ds;
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    

    2.6 总结

    基于XML配置 基于注解配置
    Bean定义 <bean id="..." class="..."/> @Component即衍生类@Repository、@Service、@Controller
    Bean名称 通过id或name指定 @Component("…")
    Bean注入 <property>或者通过p命名空间 @Autowired按类型注入、@Qualifier按名称注入
    生命过程、Bean作用范围 init-method、destroy-method;范围scope属性 @PostConstruct初始化、@PreDestroy销毁、@Scope设置作用范围
    适合场景 Bean来自第三方,使用其他Bean Bean的实现类由用户自己开发

    3. Spring整合Junit

    • 导入坐标

      <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.2.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
        </dependencies>
      
    • 使用@RunWith注解替换原有运行器

      @RunWith(SpringJUnit4ClassRunner.class)
      public class AccountTest {}
      
    • 使用@ContextConfiguration指定spring配置文件的位置

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(locations = "classpath:bean.xml")
      public class AccountTest {}
      
    • 使用@Autowired给测试类中的变量注入数据

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(locations = "classpath:bean.xml")
      public class AccountTest {
      
          @Autowired
          private IAccountService as;
      }
      

    完整的使用:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = "classpath:bean.xml")
    public class AccountTest {
    
        @Autowired
        private IAccountService as;
    
        @Test
        public void testFindAll(){
            List<Account> all = as.findAll();
            for (Account account : all) {
                System.out.println(account);
            }
        }
    }
    

    4. 基于完全注解的CURD

    4.1 创建表

    首先需要在数据库中创建表,并插入数据:

    create table account(
    	id int primary key auto_increment,
    	name varchar(40),
    	money float
    )character set utf8 collate utf8_general_ci;
    
    insert into account(name,money) values('aaa',1000);
    insert into account(name,money) values('bbb',1000);
    insert into account(name,money) values('ccc',1000);
    

    使用select查询:

    mysql> select * from account;
    +----+------+-------+
    | id | name | money |
    +----+------+-------+
    |  1 | aaa  |  1000 |
    |  2 | bbb  |  1000 |
    |  3 | ccc  |  1000 |
    +----+------+-------+
    3 rows in set (0.00 sec)
    

    4.2 创建工程

    创建Maven工程,然后导入需要的pom.xml中导入需要的坐标:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>SpringAllAnnotationAccount</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.2.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.2.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.20</version>
            </dependency>
            <dependency>
                <groupId>commons-dbutils</groupId>
                <artifactId>commons-dbutils</artifactId>
                <version>1.4</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>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    </project>
    

    4.3 创建实体类

    创建对应于表的实体类,并实现序列化接口:

    public class Account implements Serializable {
    
        private Integer id;
        private String name;
        private Float money;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Float getMoney() {
            return money;
        }
    
        public void setMoney(Float money) {
            this.money = money;
        }
    
        @Override
        public String toString() {
            return "Account{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", money=" + money +
                    '}';
        }
    }
    

    4.4 持久层

    public interface IAccountDao {
    
        List<Account> findAll();
    
        Account findById(Integer id);
    
        void saveAccount(Account account);
    
        void updateAccount(Account account);
    
        void deleteAccount(Integer id);
    }
    
    @Repository("accountDao")
    public class IAccountDaoImpl implements IAccountDao {
    
        @Autowired
        private QueryRunner runner;
    
        public List<Account> findAll() {
            try {
                return runner.query("select * from account", new BeanListHandler<Account>(Account.class));
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    
        public Account findById(Integer id) {
            try {
                return runner.query("select * from account where id=?", new BeanHandler<Account>(Account.class), id);
            }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 id) {
            try {
                runner.update("delete from account where id=?",id);
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    
    

    4.5 业务层

    public interface IAccountService {
        List<Account> findAll();
    
        Account findById(Integer id);
    
        void saveAccount(Account account);
    
        void updateAccount(Account account);
    
        void deleteAccount(Integer id);
    }
    
    
    @Service("accountService")
    public class AccountServiceImpl implements IAccountService {
    
        @Autowired
        private IAccountDao accountDao;
    
        public List<Account> findAll() {
            return accountDao.findAll();
        }
    
        public Account findById(Integer id) {
            return accountDao.findById(id);
        }
    
        public void saveAccount(Account account) {
            accountDao.saveAccount(account);
        }
    
        public void updateAccount(Account account) {
            accountDao.updateAccount(account);
        }
    
        public void deleteAccount(Integer id) {
            accountDao.deleteAccount(id);
        }
    }
    

    4.6 配置类

    public class JdbcConfig {
        @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="runner")
        @Scope("prototype")
        public QueryRunner createQueryRunner(@Qualifier("ds") DataSource dataSource){
            return new QueryRunner(dataSource);
        }
    
        @Bean(name="ds")
        public DataSource createDataSource(){
            try {
                ComboPooledDataSource ds = new ComboPooledDataSource();
                ds.setDriverClass(driver);
                ds.setJdbcUrl(url);
                ds.setUser(username);
                ds.setPassword(password);
                return ds;
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    
    
    @ComponentScan("dyliang")
    @Import(JdbcConfig.class)
    @PropertySource("classpath:jdbcConfig.properties")
    public class SpringConfiguration {
    }
    

    其中配置文件jdbcConfig.properties内容为:

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/sql_store?serverTimezone=GMT
    jdbc.username=root
    jdbc.password=1234
    

    4.7 单元测试

    最后,编写测试类并执行单元测试:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = SpringConfiguration.class)
    public class AccountTest {
    
        @Autowired
        private IAccountService as = null;
    
        @Test
        public void testFindAll() {
            List<Account> accounts = as.findAll();
            for(Account account : accounts){
                System.out.println(account);
            }
        }
    
        @Test
        public void testFindOne() {
            Account account = as.findById(1);
            System.out.println(account);
        }
    
        @Test
        public void testSave() {
            Account account = new Account();
            account.setName("test anno");
            account.setMoney(12345f);
            as.saveAccount(account);
    
        }
    
        @Test
        public void testUpdate() {
            Account account = as.findById(4);
            account.setMoney(23456f);
            as.updateAccount(account);
        }
    
        @Test
        public void testDelete() {
            as.deleteAccount(4);
        }
    }
    

    t> accounts = as.findAll();
    for(Account account : accounts){
    System.out.println(account);
    }
    }

    @Test
    public void testFindOne() {
        Account account = as.findById(1);
        System.out.println(account);
    }
    
    @Test
    public void testSave() {
        Account account = new Account();
        account.setName("test anno");
        account.setMoney(12345f);
        as.saveAccount(account);
    
    }
    
    @Test
    public void testUpdate() {
        Account account = as.findById(4);
        account.setMoney(23456f);
        as.updateAccount(account);
    }
    
    @Test
    public void testDelete() {
        as.deleteAccount(4);
    }
    

    }

    
    
    展开全文
  • Spring的IOC理论和使用

    2020-11-09 23:22:30
    没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方。 采用XML方式配置Bean的时候,Bean的定义信息是和实现...

    IOC本质

    控制反转IoC(Inversion of Control)是一种设计思想,DI(依赖注入)是实现IoC的一种方法。没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方。

    采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到零配置的目的。

    控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方式是依赖注入(Dependency Injection,DI)。

    Spring的使用

    样例1:

    1.pom.xml文件中加入Spring的依赖

        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.3.0</version>
            </dependency>
        </dependencies>

    2.创建pojo,一定要有set方法,因为Spring是需要通过set方法注入去生成对象

    package com.cbbpp.pojo;
    
    public class Hello {
        private String str;
    
        public Hello() {
        }
        public Hello(String str) {
            this.str = str;
        }
        @Override
        public String toString() {
            return "Hello{" +
                    "str='" + str + '\'' +
                    '}';
        }
        public String getStr() {
            return str;
        }
        public void setStr(String str) {
            this.str = str;
        }
    }
    

    3.添加Beans.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">
    
        <!--使用Spring来创建对象,在Spring这些都称为Bean-->
        <bean id="hello" class="com.cbbpp.pojo.Hello">
            <property name="str" value="Spring"/>
        </bean>
    
    </beans>
    
    <!--Beans就是IoC容器,用来托管bean(对象)-->

    4.测试使用

    import com.cbbpp.pojo.Hello;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
        public static void main(String[] args) {
    
            //获取Spring的上下文对象,拿到Spring容器
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            //我们的对象现在都在Spring中被管理了,我们要使用,直接去里面取出来就可以了
            Hello hello = (Hello) context.getBean("hello");
            System.out.println(hello.toString());
    
        }
    }
    

    控制台输入结果:

    Hello{str='Spring'}
    
    Process finished with exit code 0
    

    样例2:

    1.同上

    2.设置接口和实现类

    //接口UserDao 
    package com.cbbpp.dao;
    
    public interface UserDao {
        void getUser();
    }
    //接口UserService 
    package com.cbbpp.service;
    
    public interface UserService {
        void getUser();
    }
    
    
    //实现类UserDaoImpl 
    package com.cbbpp.dao;
    
    public class UserDaoImpl implements UserDao{
        public void getUser() {
            System.out.println("默认获取接口的数据");
        }
    }
    
    //实现类MysqlDaoImpl 
    package com.cbbpp.dao;
    
    public class MysqlDaoImpl implements UserDao{
        public void getUser() {
            System.out.println("Mysql的数据");
        }
    }
    
    //实现类OracleDaoImpl 
    package com.cbbpp.dao;
    
    public class OracleDaoImpl implements UserDao{
        public void getUser() {
            System.out.println("Oracle的数据");
        }
    }
    
    //实现类SqlServerDaoImpl 
    package com.cbbpp.dao;
    
    public class SqlServerDaoImpl implements UserDao{
        public void getUser() {
            System.out.println("sqlServer的数据");
        }
    }
    
    //实现类UserServiceImpl 
    package com.cbbpp.service;
    
    import com.cbbpp.dao.UserDao;
    import com.cbbpp.dao.UserDaoImpl;
    
    public class UserServiceImpl implements UserService{
    
    
        private UserDao userDao;
    
        public void setUserDao(UserDao userDao){
            this.userDao = userDao;
        }
    
    
        public void getUser() {
            userDao.getUser();
        }
    }
    
    

    3.添加Beans.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">
    
        <!--使用Spring来创建对象,在Spring这些都称为Bean-->
        <bean id="mysqlImpl" class="com.cbbpp.dao.MysqlDaoImpl"/>
        <bean id="OracleImpl" class="com.cbbpp.dao.OracleDaoImpl"/>
        <bean id="SqlServerImpl" class="com.cbbpp.dao.SqlServerDaoImpl"/>
        <bean id="UserImpl" class="com.cbbpp.dao.UserDaoImpl"/>
    
    
        <!--ref是用来应用Spring容器中已经创建好的对象,value是直接手动设置的具体值(基本类型)-->
        <bean id="UserServiceImpl" class="com.cbbpp.service.UserServiceImpl">
            <property name="userDao" ref="OracleImpl"/>
        </bean>
    
    </beans>
            <!--Beans就是IoC容器,用来托管bean(对象)-->

    4.测试使用

        public static void main(String[] args) {
    
            ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
            UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");
            userServiceImpl.getUser();
        }
    
    

    控制台输入结果: 

    Oracle的数据
    
    Process finished with exit code 0

     

    控制:谁来控制对象的创建,在传统的应用程序中对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的

    反转:程序本身不参加创建对象,而变成被动的接收对象

    依赖注入:就是利用set方法来进行注入的

    IOC是一种编程思想,由主动的编程变成被动的接收

    我们使用Spring彻底不要再去程序中进行改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓IoC,也就是:对象由Spring来创建、管理、装配

    我们只需要玩配置文件就行了,程序不用改动任何

    展开全文
  • Spring IOC的注解配置

    万次阅读 2020-05-13 15:11:43
    Spring IOC的注解配置 (一)简述 上回说到,我们可以使用书写XML配置文件的方式来让spring产生我们需要的Bean对象,并放入容器中。但是,书写配置文件是一件非常繁琐的事情,而且一旦配置文件内容很多,阅读起来也...

    Spring IOC的注解配置

    (一)简述

    上回说到,我们可以使用书写XML配置文件的方式来让spring产生我们需要的Bean对象,并放入容器中。但是,书写配置文件是一件非常繁琐的事情,而且一旦配置文件内容很多,阅读起来也是一件让人头疼的事,所以,我们急需一种部分或者完全摆脱配置文件的配置方式。

    下面我们就来看看spring的注解配置方式。注解配置和用配置文件配置相比,只是配置的形式不一样,最终达到的目的是基本相同的。就好比坐飞机去北京和坐高铁去北京,虽然使用的交通工具不一样,但是都达到了去北京的目的。

    (二)注解分类

    用来配置的注解差不多可以这样分类:用于创建对象的、用于注入数据的、用于改变作用范围的、用于在生命周期中添加逻辑的。这些注解将取代XML文件中的一些配置内容,但是不能彻底摆脱XML文件(后面会将如何彻底摆脱XML文件)。

    首先我们要在XML中引入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">
    
    </beans>
    

    然后,我们要加上扫描器,这样spring就能找到带有用于创建对象的注解的类,然后才能将他们实例化并纳入spring IOC容器内:

    <?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.demo" />
    </beans>
    

    这里的base-package就是指所有需要加入容器的Bean所在的包。有了扫描器之后,我们就来看看如何使用这四类注解。

    1. 用于创建对象

    这类注解一共有四个,分别是:@Component、@Controller、@Service和@Repository,他们的作用相当于在XML配置文件中书写<bean />标签。

    首先,我们来看@Component注解,他的功能就是将当前对象存入spring IOC容器中。@Component是一种通用名称,泛指任意可以通过Spring来管理的组件,@Controller, @Service, @Repository则是@Component的扩展,通常用来表示某种特定场合下的组件,并且Spring框架会根据这种应用场景做些定制,比如@Repository同时具备了自动化的异常转换。@Repository用来表示Dao层组件,@Service则用来表示Service层组件, @Controller则用来表示Controller层组件。

    因此,在不考虑特殊的定制情况时,这四个注解完全一样,可以混用。但是一般我们还是根据组件的性质来选择。我们随便写一个看看:

    package com.demo;
    
    import org.springframework.stereotype.Repository;
    
    @Repository
    public class UserDao {
        public void getUser(){
            System.out.println("getUser被调用了");
        }
    }
    

    这四个注解都有一个参数,用来指定Bean对象的名称,如果不写(我这里就没写),默认为类名且首字母改小写。这个注解相当于我们在XML中配置了:

    <bean id="userDao" class="com.demo.UserDao" />
    

    2. 用于注入数据

    有了对象我们可能还要注入数据,这类注解常用的有:@Value、@Autowired、@Resource,这三个注解的功能相当于<bean />标签中的<property />标签,@Value负责注入基本类型,而另外两个负责注入对象类型(依赖注入)。

    @Value没啥好讲的,直接在注解的属性里面写上要注入的值就行,另外两个可能会有点复杂。

    @Autowired默认按照类型匹配的方式进行注入 ,可以用于成员变量、setter方法、构造器函数等,使用@Autowired注解须有且仅有一个与之类型匹配的Bean对象,若存在多个匹配的Bean时,会按照名称匹配,若始终找不到匹配的对象Spring容器将抛出异常(若不想抛出异常可给注解添加属性:required=false)。我们还可以通过@Qualifier注解指定注入Bean对象的名称,@Autowired和@Qualifier结合使用时,自动注入的策略就从按类型匹配转变成按名称匹配了。

    在这里插入图片描述

    在这里插入图片描述
    使用@Resource注解以后,spring判断该注解name属性是否为空,如果为空,则会让当前属性名和spring IOC容器中的Bean对象的名称做匹配,如果匹配成功则赋值,如果匹配不成功,则会按照spring配置文件class类型进行匹配,如果还匹配不成功,则报错。如果有name属性,则会按照name属性的值和spring IOC容器中的Bean对象的名称进行匹配,匹配成功,则赋值,不成功则报错。

    在这里插入图片描述

    3. 用于改变作用范围

    这一类注解只有一个,就是@Scope,相当于<bean />标签中的scope属性。

    @Scope用来改变Bean对象的作用范围,属性可以填以下几个值,与XML配置中的一样:

    1. singleton :单例模式
    2. prototype :多例模式
    3. request :request域,需要在web环境
    4. session :session域,需要在web环境
    5. application: context域,需要在web环境
    6. globalsession 集群环境的session域,需要在web环境

    4. 用于在生命周期中添加逻辑

    这一类注解主要有两个,@PostConstruct和@PreDestroy,用在方法上,相当于<bean />标签中的init-method属性和destroy-method属性。

        @PostConstruct
        public void init() {
        	System.out.println("初始化方法......");
        }
        
        @PreDestroy
        public void destroy() {
        	System.out.println("销毁方法......");
        }
    

    看了这么多注解,我们来总结一下,其实这里的每一个注解都对应了以前XML中的一种配置功能,所以只要对应着记忆还是很容易的。

    类型 注解 对应XML元素
    用于创建对象 @Component、@Controller、@Service、@Repository <bean />标签
    用于注入数据 @Value、@Autowired、@Resource <bean />标签中的<property />标签
    用于改变作用范围 @Scope <bean />标签中的scope属性
    用于在生命周期中添加逻辑 @PostConstruct、@PreDestroy <bean />标签中的init-method属性和destroy-method属性

    (三)纯注解配置

    纯注解配置使得我们终于可以抛弃XML文件了,不过,我们需要书写一个配置类来代替他的功能。

    我们来想想这个配置类中可能有哪些东西,首先,spring如何知道他是一个配置类?我们得给他添加一个配置类专用的注解,这个注解就是@Configuration,有了他之后这个类就会被当做一个配置类。

    然后,我们还讲过我们以前在XML中配置过一个扫描器,这个在配置类中也变成了一个注解,他就是@ComponentScan,我们只要在里面填入我们需要spring扫描的包即可。注意,这边如果要填入多个包,我们需要写成数组形式。我们来看一个例子:

    package com.demo;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @ComponentScan("com.demo")
    public class Config {
    
    }
    
    package com.demo;
    
    import org.springframework.stereotype.Repository;
    
    @Repository
    public class UserDao {
        public void getUser(){
            System.out.println("getUser被调用了");
        }
    }
    
    
    package com.demo;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
        @Autowired
        private UserDao userDao;
    
        public void get(){
            userDao.getUser();
    }
    

    这个例子非常简洁,主要目的就是展示一下纯注解的配置模式。很显然,我们以前在XML中配置的东西一个都没有少。这也是印证了我之前说的一句话:XML配置和注解配置,只是形式不一样,最后达成的目的是基本一致的。什么?你问能不能把配置类也省了?居然有比我还懒的人?当然,是可以的,不过需要出门右拐去看看springboot,领略一下约定大于配置,体会一下一行代码都不写就能跑起来一个应用程序的潇洒。

    不过,十分不推荐初学者直接去看springboot,原因很简单,如果不懂spring的原理,调试的时候你会怀疑人生的。我们学spring,除了学习框架怎么使用,更多的是学习一下什么叫Java顶级项目、什么称得上规范、什么是设计模式。只有能领略到这些,才算是真的把spring学到家了,到那时候自己手写一个spring框架也不是不可能了。

    2020年5月13日

    展开全文
  • Spring学习笔记--IoC与DI

    2019-08-02 05:13:38
     IoC  程序中的之间的关系,不用代码控制,而完全是由容器来控制。在运行阶段,容器会根据配置信息直接把他们的关系注入到组件中  强调程序依赖关系由Spring容器控制  DI  以前的开发场景中,我们往往通过...
  • Spring实例–注解实现一文中,虽然用了很多注解去完成Ioc等操作,但是仍然需要XML去配置扫描的包等等。接下来就说说怎么完全的舍弃XML配值文件吧。 Spring实例–注解实现的XML配置文件 <?xml version="1.0" ...
  • Parsley是一个开源的IOC容器也是一个完全解耦的基于消息中心机制的消息框架,它还为我们提供了一些很有用的工具类。Favous平台即将使用parsley的架构,来配置所有的bean,业务系统以后也会逐渐转向parsley框架,以...
  • Spring有两个自带接口、BeanFactory和FactoryBean、这两个接口虽然名字差不多、但是实际上确实完全不一样的两种东西一、BeanFactoryBeanFactory定义了IOC容器的最基本形式、并提供了IOC容器应遵守的的最基本的接口、...
  • spring学习笔记

    2020-07-02 18:02:49
    控制反转IOC,是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法,没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序...
  • Spring的核心特性就是控制反转(IOC)和切面编程(AOP),Spring通过IOC容器来实现这些特性,IOC容器中,用户定义的对象以Bean的形式存放,然后由Spring解决Bean之间的依赖关系,并且对Bean进行代理从而实现AOP编程。...
  • SpringBoot框架

    2020-08-16 16:59:09
    ​ Spring框架从4.x版本开始推荐使用注解形式来对java 应用程序进行开发与配置,并且可以完全替代原始的Xml+注解形式的开发。 在使用注解形式进行项目开发与环境配置时,Spring 框架提供了针对环境配置与业务bean开发...
  • 配置元数据

    2015-04-19 23:54:29
    Spring IoC容器使用了一种方式配置元数据;这些元数据配置要表达:你如何以一个开发者告诉 Spring容器去实例化、配置和在应用中组合对象。... IoC 容器本身与配置元数据的方式中是完全接偶的。目前,很多开发
  • 资源以CSV文件(5个问题)的形式存储问题和各种答案。 问题可以从多个选项中选择,也可以免费答案-根据您的意愿和判断力。 应用程序应仅从CSV文件中输出测试题,并选择可能的答案。 要求: 该应用程序必须具有一...
  • springboot自动配置是如何实现的?

    千次阅读 2019-03-28 17:33:29
    什么是SpringBoot自动配置? ​ springboot的自动...​ “自动”的表现形式就是我们只需要引我们想用功能的包,相关的配置我们完全不用管,springboot会自动注入这些配置bean,我们直接使用这些bean即可。 Sprin...
  • Liferay Portal发布新版本 3.0分企业版本和专业版本,其中专业版完全采用基于Spring框架(http://www.springframework.org)的轻量级架构,...从技术的角度,这足以证明:基于IoC容器和AOP的轻量级架构完全可以取代EJB
  • SpringBoot中@Configuration注解

    千次阅读 2020-04-25 22:44:55
    传统意义上的 spring 应用都是基于 xml 形式来配置 bean 的依赖关系。然后通过spring容器在启动的时候,把bean进行初始化并且,如果bean之间存在依赖关系,则分析这些已经在IoC容器中的bean根据依赖关系进行组装。在...
  • 对于不同的调用者,不会因为需求不同,赋予它任意的性质——即这种类只会一种或少数形式创建出对象,完全可以事先创建创建、而后供人调用。 Spring的IOC容器里的对象的存在形式默认就是单例的。 常用于工具类,IO类...
  • 2021-01-14

    2021-01-14 21:39:48
    “自动”的表现形式就是我们只需要引我们想用功能的包,相关的配置我们完全不用管,springboot会自动注入这些配置bean,我们直接使用这些bean即可。 2.总结springboot如何处理异常的 在 SpringBoot 中如何自定义...
  • 本资源包括struts的学习程序,能够完全运行,当然,我是完全调试运行出来的,都是源代码原封上传,还有说明文档。还有自我总结资料,放到下一个文件夹当中上传,这里压缩只有这么多了,希望能去下载,那个全部是文档...
  • easyjweb 开发文档

    2011-06-10 16:40:58
    框架设计构思来源于国内众多项目实践,框架的设计及实现借鉴当前主要流行的开源Web框架,如Rails、Struts、JSF、Tapestry等,吸取其优点及精华,是一个完全由来自的中国开源爱好者开发,文档及注释全部为中文的开源...
  • easyjweb1.2

    2009-10-11 13:24:52
    框架设计构思来源于国内众多项目实践,框架的设计及实现借鉴当前主要流行的开源Web框架,如Rails、Struts、JSF、Tapestry等,吸取其优点及精华,是一个完全由来自的中国开源爱好者开发,文档及注释全部为中文的开源...
  • 它主要有简单小巧的IoC, ORM,数据路由,缓存集成,分布式唯一id等等功能。 albianj诞生于2011年,它的创建并不是为了解决某个公司的问题,而纯粹是为了度过我的 业余时间。当时的想法其实很简单,就是想把我这...
  • 软件工程教程

    热门讨论 2012-07-06 23:10:29
    通过付费下载的形式来盈利的,现在国内鲜见成功者。 第三类开发者 和第二类开发者类似。开发者提交的应用开发数目远超游戏开发。 任务2 软件开发计划 任务2 软件开发计划 软件开发计划 软件开发计划 问题...
  • Spring中文帮助文档

    热门讨论 2013-08-05 14:40:17
    3.10. 以J2EE RAR文件的形式部署Spring ApplicationContext 3.11. 基于注解(Annotation-based)的配置 3.11.1. @Autowired 3.11.2. 基于注解的自动连接微调 3.11.3. CustomAutowireConfigurer 3.11.4. @...
  • Spring API

    2009-09-24 18:15:56
    3.10. 以J2EE RAR文件的形式部署Spring ApplicationContext 3.11. 基于注解(Annotation-based)的配置 3.11.1. @Autowired 3.11.2. 基于注解的自动连接微调 3.11.3. CustomAutowireConfigurer 3.11.4. @...
  • java面试题

    2018-04-27 19:55:38
    答:断言,可以将断言看成是异常处理的一种高级形式,可以用来判断某个特定的表达式或值是否为真。 接口是否可以继承接口?抽象类是否可以实现接口?抽象类是否可以继承实体类? 答:接口可以继承接口,抽象类可以...
  • 头条一面:Spring IOC容器中只存放单例Bean吗? 热乎乎的面经:Spring中Scheduled和Async两种调度方式有啥区别? 进大厂,到底需要掌握哪些核心技能? 面试官:如果让你设计一个高并发的消息中间件,你会怎么做? ...
  • springmybatis

    2015-09-05 06:54:28
    MyBatis 目录(?)[-] mybatis实战教程mybatis in action之一开发环境搭建 mybatis实战教程mybatis in action之二以接口的方式编程 mybatis实战教程mybatis in action之三实现数据的增删改查 mybatis实战教程mybatis ...

空空如也

空空如也

1 2
收藏数 30
精华内容 12
关键字:

ioc完全形式