02-SpringIoC and DI Annotation Development

Posted by anthonyfellows on Mon, 07 Mar 2022 19:11:53 +0100

1.Spring Configuration Data Source

1.1 Role of data sources (connection pools)

Data sources (connection pools) are available to improve program performance

Pre-instantiate the data source to initialize partial connection resources

Get from data source when using connection resources

Return the connected resource to the data source after use

Common data sources (connection pools): DBCP, C3P0, BoneCP, Druid, etc.

Development steps

1. Importing coordinates of data sources and database-driven coordinates

(2) Creating data source objects

(3) Setting up basic connection data for data sources

(4) Using data sources to obtain and return connected resources

1.2 Manual creation of data sources

1. Import coordinates of c3p0 and druid

<!-- C3P0 Connection Pool -->
<dependency>
    <groupId>c3p0</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.1.2</version>
</dependency>
<!-- Druid Connection Pool -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

1. Import mysql database driver coordinates

<!-- mysql drive -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.39</version>
</dependency>

(2) Create C3P0 connection pool

@Test
public void testC3P0() throws Exception {
	//create data source
	ComboPooledDataSource dataSource = new ComboPooledDataSource();
	//Setting database connection parameters
    dataSource.setDriverClass("com.mysql.jdbc.Driver");    	               	               dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
    dataSource.setUser("root");
    dataSource.setPassword("root");
	//Get Connection Object
	Connection connection = dataSource.getConnection();
	System.out.println(connection);
}

(2) Create Druid connection pool

@Test
public void testDruid() throws Exception {
    //create data source
    DruidDataSource dataSource = new DruidDataSource();
    //Setting database connection parameters
    dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
    dataSource.setUrl("jdbc:mysql://localhost:3306/test");   
    dataSource.setUsername("root");
    dataSource.setPassword("root");
    //Get Connection Object
    Connection connection = dataSource.getConnection();    
    System.out.println(connection);
}

(3) Extracting jdbc.properties profile

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root

(4) Read jdbc. Properrties Profile Create Connection Pool

@Test
public void testC3P0ByProperties() throws Exception {
    //Load JDBC under the class path. Properties
    ResourceBundle rb = ResourceBundle.getBundle("jdbc");
    ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
    dataSource.setDriverClass(rb.getString("jdbc.driver"));   
    dataSource.setJdbcUrl(rb.getString("jdbc.url")); 
    dataSource.setUser(rb.getString("jdbc.username")); 
    dataSource.setPassword(rb.getString("jdbc.password"));
    Connection connection = dataSource.getConnection();   
    System.out.println(connection);
}

1.3 Spring Configuration Data Source

Creation of a DataSource can be left to the Spring container to complete

DataSource has parameterized construction methods, and Spring instantiates objects by default with parameterized construction methods

DataSource uses the set method to set the database connection information, while Spring uses the set method for string injection

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
    <property name="user" value="root"/>
    <property name="password" value="root"/>
</bean>

Test Getting Data Sources from Containers

ApplicationContext applicationContext = new 
           ClassPathXmlApplicationContext("applicationContext.xml");
               DataSource dataSource = (DataSource) 
applicationContext.getBean("dataSource");
Connection connection = dataSource.getConnection();
System.out.println(connection);

1.4 Extract jdbc configuration file

applicationContext.xml loads jdbc. Properrties configuration file to get connection information.

First, you need to introduce the context namespace and constraint path:

Namespace: xmlns:context=" http://www.springframework.org/schema/context "

Constraint Path: http://www.springframework.org/schema/context

​ http://www.springframework.org/schema/context/spring-context.xsd

<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

1.5 Key Points of Knowledge

Spring Container Load properties File

<context:property-placeholder location="xx.properties"/>
<property name="" value="${key}"/>

2. Spring Annotation Development

2.1 Spring original annotations

Spring is a framework of light code and reconfiguration, which is heavy to configure and affects development efficiency, so annotation development is a trend. Replacing xml configuration file with annotation can simplify configuration and improve development efficiency.

The Spring original annotations are primarily alternative configurations

annotationExplain
@ComponentUse for instantiating beans on classes
@ControllerUse for instantiating beans on web-tier classes
@ServiceUse for instantiating beans on service layer classes
@RepositoryUse for instantiating beans on dao layer classes
@AutowiredUse on fields for type-dependent injection
@QualifierUsed with @Autowired for dependency injection by name
@ResourceEquivalent to @Autowired+@Qualifier, injected by name
@ValueInjecting generic attributes
@ScopeScope of label beans
@PostConstructLabeling the method using the method is the Bean's initialization method
@PreDestroyLabel the method as Bean's destruction method using the method

Be careful:

Developing with annotations requires an applicationContext. Configure component scanning in XML to specify which package and the beans under it need to be scanned to identify classes, fields, and methods configured using annotations.

<!--Annotated component scan-->
<context:component-scan base-package="com.itheima"></context:component-scan>

Identifying UserDaoImpl with @Compont or @Repository requires Spring to instantiate.

//@Component("userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
    	System.out.println("save running... ...");
    }
}

Identifying UserServiceImpl with @Compont or @Service requires Spring for instantiation

userDao injection using @Autowired or @Autowired+@Qulifier or @Resource

//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    /*@Autowired
    @Qualifier("userDao")*/
    @Resource(name="userDao")
    private UserDao userDao;
    @Override
    public void save() {       
   	  userDao.save();
    }
}

String injection using @Value

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Value("Injecting normal data")
    private String str;
    @Value("${jdbc.driver}")
    private String driver;
    @Override
    public void save() {
        System.out.println(str);
        System.out.println(driver);
        System.out.println("save running... ...");
    }
}

Label Bean's range with @Scope

//@Scope("prototype")
@Scope("singleton")
public class UserDaoImpl implements UserDao {
   //Omit code here
}

Use @PostConstruct label initialization method and @PreDestroy label destroy method

@PostConstruct
public void init(){
	System.out.println("Initialization Method....");
}
@PreDestroy
public void destroy(){
	System.out.println("destroy-method.....");
}

2.2 New Spring Notes

The above annotations do not completely replace the xml configuration file, and the following configurations need to be replaced by annotations:

Configuration of non-custom beans:

Load the configuration of the properties file: context:property-placeholder

Configuration for component scanning: context:component-scan

Introduce additional files:

annotationExplain
@ConfigurationUsed to specify that the current class is a Spring configuration class from which annotations are loaded when creating containers
@ComponentScanUsed to specify the package that Spring will scan when initializing the container. Acts like <context:component-scan base-package="com.itheima"/> in Spring's xml configuration file
@BeanUsing a method, the label stores the method's return value in the Spring container
@PropertySourceFor loading. Configuration in the properties file
@ImportFor importing other configuration classes

@Configuration

@ComponentScan

@Import

@Configuration
@ComponentScan("com.itheima")
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {
}

@PropertySource

@value

@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
    @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

@Bean(name="dataSource")
public DataSource getDataSource() throws PropertyVetoException { 
    ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
    dataSource.setDriverClass(driver);
    dataSource.setJdbcUrl(url);
    dataSource.setUser(username);
    dataSource.setPassword(password);
    return dataSource;
} 

Test Load Core Configuration Class Create Spring Container

@Test
public void testAnnoConfiguration() throws Exception {
ApplicationContext applicationContext = new 
          AnnotationConfigApplicationContext(SpringConfiguration.class);    UserService userService = (UserService)    
    applicationContext.getBean("userService");
    userService.save();
    DataSource dataSource = (DataSource) 
    applicationContext.getBean("dataSource");
    Connection connection = dataSource.getConnection(); 
    System.out.println(connection);
    }

3. Spring Integrates Junit

3.1 Problems with the original Junit test Spring

In the test class, each test method has the following two lines of code:

 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
 IAccountService as = ac.getBean("accountService",IAccountService.class);

The purpose of these two lines of code is to get the container and, if not written, prompt for a null pointer exception. Therefore, it cannot be easily deleted.

3.2 Ideas for solving the above problems

Let SpringJunit be responsible for creating the Spring container, but you need to tell it the name of the configuration file

Test Bean s will need to be injected directly into the test class

3.3 Spring Integrated Junit Step

1. Import spring integrated Junit coordinates

(2) Replace the original run time with the @Runwith comment

(3) Use @ContextConfiguration to specify profiles or configuration classes

(4) Injecting objects that need to be tested with @Autowired

Create test methods for testing

3.4 Spring Integrated Junit Code Implementation

1. Import spring integrated Junit coordinates

<!--Notice here that spring5 Version requirements and above junit Version of must be 4.12 And above-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

(2) Replace the original run time with the @Runwith comment

@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {
}

(3) Use @ContextConfiguration to specify profiles or configuration classes

@RunWith(SpringJUnit4ClassRunner.class)
//Load spring Core Configuration File
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//Loading spring core configuration class
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
}

(4) Injecting objects that need to be tested with @Autowired

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    @Autowired
    private UserService userService;
}

Create test methods for testing

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})public class SpringJunitTest {
    @Autowired
    private UserService userService;
    @Test
    public void testUserService(){
   	 userService.save();
    }
}

Spring Integrated Junit Step

1. Import spring integrated Junit coordinates

(2) Replace the original run time with the @Runwith comment

(3) Use @ContextConfiguration to specify profiles or configuration classes

(4) Injecting objects that need to be tested with @Autowired

Create test methods for testing

Topics: Java Spring