Spring - Use IoC and DI to simulate registration cases, annotations to configure IoC and DI

Catalog

1. Simulate registration cases using IoC and DI (XML configuration)

Jump to Directory

  • data base
CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(40) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

Some classes and interfaces used

  • Classes and interfaces
// User class under domain package
@Getter
@Setter
@ToString
public class User {
    private Long id;
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

//--------------------------------------------

// UserController class under controller package
// Controller that simulates the Action / Spring MVC of Struct2
public class UserController {

    @Setter
    private UserService service;

    public String register(){
        System.out.println("Registration Request");
        service.register(new User("Chaoyang", 100));
        return "success";
    }
}

//--------------------------------------------

// UserService interface and implementation class under service package
public interface UserService {
    // register
    void register(User u);
}
public class UserServiceImpl implements UserService {

    @Setter
    private UserDao dao;

    public void register(User u) {
        System.out.println("Registration Method");
        dao.save(u);
    }
}

//--------------------------------------------

// UserDao interface and implementation class under dao package
public interface UserDao {
    // Save user information
    void save(User u);
}
public class UserDaoImpl implements UserDao {

    @Setter
    private DataSource dataSource;

    @SneakyThrows // Secretly throw checked exception
    public void save(User u) {
        System.out.println("Save Operation");
        @Cleanup // Processing resource shutdown
        Connection conn = dataSource.getConnection();
        String sql = "INSERT INTO user(name ,age) VALUES(?,?)";
        @Cleanup
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1, u.getName());
        ps.setInt(2, u.getAge());
        ps.executeUpdate();
    }
}
  • db.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=1111
jdbc.initialSize=2
  • xml file (focus operation)
<?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 https://www.springframework.org/schema/context/spring-context.xsd">

    <!--from classpath Root path to load db.properties file-->
    <!--<context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"/>-->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--Configure one druid Connection Pool-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="initialSize" value="${jdbc.initialSize}"/>
    </bean>

    <!--To configure DAO-->
    <bean id="userDao" class="com.sunny._06_register.dao.impl.UserDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--To configure service-->
    <bean id="userService" class="com.sunny._06_register.service.impl.UserServiceImpl">
        <property name="dao" ref="userDao"/>
    </bean>

    <!--To configure Action/Controller
        //If Struct2's Action is used, the scope of the bean should be multiple: scope="prototype"
        //If you use the SpringMVC Controller, the scope of the bean should be singleton at this point
    -->
    <bean id="userController" class="com.sunny._06_register.controller.UserController">
        <property name="service" ref="userService"/>
    </bean>
</beans>

  • Test Class
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RegisterTest {

    // @Autowired: Indicates that a corresponding bean is found from the Spring IoC container by type and automatically injected into a field
    @Autowired
    private UserController uc;

    @Test
    public void test(){
        uc.register();
    }
}
  • output

2. Notes on configuring IoC and DI

 *Previous XML configuration:
 *  <bean id="accountService" class="com.sunny.service.impl.AccountServiceImpl"
 *        scope=""  init-method="" destroy-method="">
 *      <property name=""  value="" | ref=""></property>
 *  </bean>
 *
 *Used to create objects
 *They do the same thing as writing a <bean>tag in an XML configuration file
 *      Component:
 *Role: Used to store the current class object in the spring container
 *Attributes:
 * value: The id used to specify the bean.When we don't write, its default value is the current class name, with the first letter lowercase.
 * Controller: Typically used in the presentation layer
 * Service: Typically used in the business tier
 * Repository: Typically used in persistence layers
 * The three notes above have the same roles and properties as Component.
 * The three of them are the spring framework that provides us with clear, three-tier notes to use to make our three-tier objects clearer
 *
 *
 *Used to inject data
 *They do the same thing as writing a <property>tag in the bean tag in the xml configuration file
 *      Autowired:
 *Role: Automatically inject by type.The injection is successful as long as there is only one bean object type in the container that matches the variable type to be injected
 * Error if there are no bean s in the ioc container whose type matches the variable type to be injected.
 *If more than one type matches in the Ioc container:
 *Location:
 * Can be variable or method
 *Details:
 * The set method is not required when using annotation injection.
 *      Qualifier:
 *Role: Inject by name on top of injecting by class.It cannot be used alone when injecting class members.But you can inject method parameters (we'll talk about it later)
 *Attributes:
 * value: The id used to specify the injection bean.
 *      Resource
 *Action: Inject directly according to the id of the bean.It can be used independently
 *Attributes:
 * name: The id used to specify the bean.
 * All three injections above can only inject data of other bean types, while the basic and String types cannot be implemented with the above annotations.
 * Additionally, injection of collection types can only be done through XML.
 *
 *      Value
 *Role: Used to inject data of basic and String types
 *Attributes:
 * value: The value used to specify the data.It can use SpEL in spring (that is, spring's el expression)
 * Writing of SpEL: ${expression}
 *
 *Used to change scope of action
 *They do the same thing as using the scope attribute in the bean tag
 *      Scope
 *Role: Used to specify the scope of a bean
 *Attributes:
 * value: The value of the specified range.Common values: singleton prototype
 *
 *Understanding life cycle
 * They do the same thing as using init-method and destroy-method in bean Tags
 *      PreDestroy
 *Role: Used to specify destruction methods
 *      PostConstruct
 *Role: Used to specify the initialization method

Jump to Directory

1. DI Notes

Jump to Directory

1.1, Autowired and Qualifier annotations

Jump to Directory

Java class

public class Cat {
}
public class Person {
    //@Autowired
    private Cat c1;

/*  @Autowired
    public void setC1(Cat c1) {
        this.c1 = c1;
    }*/
    @Override
    public String toString() {
        return "Person{" +
                "c1=" + c1 +
                '}';
    }
}

By pasting @Autowired onto a field or setter method, Spring automatically finds and injects the object (Cat object) needed by that field into that object (person), which previously required manual ref injection into the Person object in XML.

  • xml configuration
    Be sure to configure DI Annotation Parser (interpret DI annotations)
    <context:annotation-config/>
    
<!--DI Annotation Parser
    In Spring Test, you can do this without pairing
    In normal tests, it must be matched;
    Typically configure in development!
-->
<context:annotation-config/>

<bean id="cat1" class="com.sunny.di.Cat"/>
<bean id="cat2" class="com.sunny.di.Cat"/>
<bean id="person" class="com.sunny.di.Person"/>
1.2. Resource Notes

Jump to Directory

// Only Cat object with id cat1 will be found, if not, it will directly error!
@Resource(name = "cat1")
private Cat c1;

Note: @Autowired and @Resource are basically the same functionality, so choose one of them for development!

1.3, Value comment

Jump to Directory
Autowired and Resource annotations are used to inject objects, and Value annotations are used to inject constant data (simple type data);

server.properties

server.port=781

Java class

public class ValueBean {
    //@Value("9999")
    @Value("${server.port}")
    private int port;

    @Override
    public String toString() {
        return "ValueBean{" +
                "port=" + port +
                '}';
    }
}

xml file

    <!--DI Annotation Parser
        In Spring Test, you can do this without pairing
        In normal tests, it must be matched;
        Typically configure in development!
    -->
    <context:annotation-config/>

    <!--Load properties file-->
    <context:property-placeholder location="classpath:db.properties, classpath:server.properties "/>
    
    <bean id="valueBean" class="com.sunny.di.ValueBean"/>


Test Class

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class DiTest {

    //@Autowired
    @Resource
    private Person person;

    @Autowired
    private ValueBean valueBean;

    @Test
    public void test(){
        System.out.println(person);
        System.out.println(valueBean);
    }
}

2. IoC Notes

Jump to Directory
bean Component Layout: The four components have the same functionality but are used to label different types of components.

  • @Component is a generic term for components that can be labeled with this comment when they are not well categorized.
  • @Repository is used to label the data access component, the DAO component.
  • @Service is used to label business tier components.
  • @Controller is used to label control layer components such as Action in struts, Controller in SpringMVC.

Configure IoC Annotation Parser

 <!--IoC Annotation parser-->
 <context:component-scan base-package="com.sunny.ioc"/>

Represents which packages and their subpackages are scanned for component annotations

Java class

// XML configuration: <bean id="myDataSource" class="com.sunny.ioc.MyDataSource"/>
// Annotation Configuration: @Component
@Component("myDataSource") //If the component does not write the value attribute value, the bean's id defaults to lowercase of the type: myDataSource
public class MyDataSource {
}

xml file

<!--DI Annotation Parser-->
<context:annotation-config/>

<!--IoC Annotation Parser-->
<context:component-scan base-package="com.sunny.ioc"/>

<!--Previously given to the Spring container to create MyDataSource objects using XML-->
<!--<bean id="myDataSource" class="com.sunny.ioc.MyDataSource"/>-->

Test Class

    @Autowired
    private MyDataSource mds;

    @Test
    public void test(){
        System.out.println(mds);
    }

Both methods can successfully create MyDataSource objects!

3. Scope annotations and initialization and destruction annotations

Jump to Directory

  • Scope annotation uses the @Scope annotation
  • Initialization annotations are pasted onto the initialization method using @PostConstruct
  • Destroy Comment Use @PreDestroy to paste on the destroy method

java class

@Component
//@Scope("prototype")//Default not written is singleton
//@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class SomeBean {
    public SomeBean() {
        System.out.println("structure SomeBean object");
    }

    @PreDestroy // Execute before destroying objects
    public void close() {
        System.out.println("destroy-method");
    }

    @PostConstruct // Execute after building object
    public void open() {
        System.out.println("Initialization Method");
    }
    public void doWork() {
        System.out.println("work");
    }
}
    <!--Old way-->
    <!--<bean id="someBean" class="com.sunny.lifecycle.SomeBean"
        init-method="open" destroy-method="open"
    />-->

    <!--To configure IoC Annotation parser-->
    <context:component-scan base-package="com.sunny.lifecycle"/>

Test Class

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class LifeCycleTest {

    @Autowired
    private SomeBean sb1;
    @Autowired
    private SomeBean sb2;

    @Test
    public void test(){
        System.out.println(sb1);
        System.out.println(sb2);
        sb1.doWork();
    }
}

4. IoC and DI are actually the same thing

Jump to Directory

  • IoC: Literally, more emphasis is on the Spring container to help us create objects
  • DI: Literally, Spring not only helps us create objects, but also sets up dependent data for them

3. Simulate registration cases using IoC and DI (Note Configuration)

Jump to Directory

  • data base
CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(40) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

Some classes and interfaces used

  • Classes and interfaces
// User class under domain package
@Getter
@Setter
@ToString
public class User {
    private Long id;
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

//--------------------------------------------

// UserController class under controller package
// Controller that simulates the Action / Spring MVC of Struct2
@Controller
public class UserController {
	//@Setter
	@Autowired
    private UserService service;

    public String register(){
        System.out.println("Registration Request");
        service.register(new User("Yang Zi", 99));
        return "success";
    }
}

//--------------------------------------------

// UserService interface and implementation class under service package
public interface UserService {
    // register
    void register(User u);
}
@Repository
public class UserServiceImpl implements UserService {
	
	//@Setter
    @Autowired // Is to find by type
    private UserDao dao;

    public void register(User u) {
        System.out.println("Registration Method");
        dao.save(u);
    }
}

//--------------------------------------------

// UserDao interface and implementation class under dao package
public interface UserDao {
    // Save user information
    void save(User u);
}
@Repository
public class UserDaoImpl implements UserDao {
	//@Setter
    @Autowired
    private DataSource dataSource;

    @SneakyThrows // Secretly throw checked exception
    public void save(User u) {
        System.out.println("Save Operation");
        @Cleanup // Processing resource shutdown
        Connection conn = dataSource.getConnection();
        String sql = "INSERT INTO user(name ,age) VALUES(?,?)";
        @Cleanup
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setString(1, u.getName());
        ps.setInt(2, u.getAge());
        ps.executeUpdate();
    }
}

  • db.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring
jdbc.username=root
jdbc.password=1111
jdbc.initialSize=2
  • xml file (focus operation)
<?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 https://www.springframework.org/schema/context/spring-context.xsd">

    <!--DI Annotation parser-->
    <context:annotation-config/>
    <!--IoC Annotation parser
        //Will automatically scan the register's subpackages
    -->
    <context:component-scan base-package="com.sunny._01_register"/>

    <!--from classpath Root path to load db.properties file-->

    <context:property-placeholder location="classpath:db.properties, classpath:server.properties "/>
    <!--<context:property-placeholder location="classpath:db.properties" ignore-resource-not-found="true"/>
    <context:property-placeholder location="classpath:server.properties" ignore-resource-not-found="true"/>-->

    <!--Configure one druid Connection Pool-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="initialSize" value="${jdbc.initialSize}"/>
    </bean>
    
</beans>
  • Test Class
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RegisterTest {

    // @Autowired: Indicates that a corresponding bean is found from the Spring IoC container by type and automatically injected into a field
    @Autowired
    private UserController uc;

    @Test
    public void test(){
        uc.register();
    }
}
  • output
183 original articles were published. 147 were praised. 140,000 visits+
Private letter follow

Tags: JDBC xml Spring SQL

Posted on Sat, 14 Mar 2020 23:56:18 -0400 by billf