Spring DI

Set up the project

Execute the following command in your workspace.
(↵ is an indication to press the enter key. Enter chooses the default value)

C:\ Command Prompt
mvn archetype:generate

Choose a number or apply filter 
    (format: [groupId:]artifactId, case sensitive contains): 2005: ↵

Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.1
7: 1.3
8: 1.4
Choose a number: 8: ↵
Define value for property 'groupId': : net.java_school
Define value for property 'artifactId': : bank
Define value for property 'version':  1.0-SNAPSHOT: : ↵
Define value for property 'package':  net.java_school: : ↵
Confirm properties configuration:
groupId: net.java_school
artifactId: bank
version: 1.0-SNAPSHOT
package: net.java_school
 Y: : ↵

Access the Scott account with SQL * PLUS and Create the following table.

create table bankaccount (
  accountno varchar2(50),
  owner varchar2(20) not null,
  balance number,
  kind varchar2(10),
  constraint PK_BANKACCOUNT primary key(accountno),
  constraint CK_BANKACCOUNT_NORMAL 
      CHECK (balance >= CASE WHEN kind='NORMAL' THEN 0 END),
  constraint CK_BANKACCOUNT_KIND CHECK (kind in ('NORMAL', 'MINUS'))
);  
create table transaction (
  transactiondate timestamp,
  kind varchar2(10),
  amount number,
  balance number,
  accountno varchar2(50),
  constraint FK_TRANSACTION FOREIGN KEY(accountno)
      REFERENCES bankaccount(accountno)
);

Create a trigger that inserts data into a transaction table when depositing or withdrawing.

create or replace trigger bank_trigger
after insert or update of balance on bankaccount
for each row
begin
  if :new.balance > :old.balance then
    insert into transaction 
    values 
    (
      systimestamp,
      'DEPOSIT',
      :new.balance - :old.balance,
      :new.balance,
      :old.accountno
    );
  end if;
  if :new.balance < :old.balance then
    insert into transaction 
    values 
    (
      systimestamp,
      'WITHDRAW',
      :old.balance - :new.balance,
      :new.balance,
      :old.accountno
    );
  end if;
end;
/

Copy https://github.com/kimjonghoon/JavaBank sources and paste them to the following locations:

src
└── main
    └── java
        └── net
            └── java_school
                └── bank
                    ├── Account.java
                    ├── Bank.java
                    ├── BankDao.java
                    ├── BankUi.java
                    ├── MyBank.java
                    ├── MyBankDao.java
                    └── Transaction.java

Edit pom.xml as shown below.

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>net.java_school</groupId>
  <artifactId>bank</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>bank</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <spring.version>6.1.5</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>2.0.6</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.4.5</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc6 -->
    <dependency>
      <groupId>com.oracle.database.jdbc</groupId>
      <artifactId>ojdbc6</artifactId>
      <version>11.2.0.4</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>bank</finalName>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

compile

C:\ Command Prompt
mvn clean compile

run

C:\ Command Prompt
mvn exec:java -Dexec.mainClass=net.java_school.bank.BankUi

Migrating to Spring project

Modify the following:

Bank.java
public void setDao(BankDao dao);//added
MyBank.java
//private BankDao dao = new MyBankDao();

//added
private BankDao dao;

public void setDao(BankDao dao) {
  this.dao = dao;
}
BankUi.java
//..omit..

import java.io.PrintStream;
import org.springframework.context.support.ClassPathXmlApplicationContext;

//..omit..
//private Bank bank = new MyBank();
private Bank bank;

public void setBank(Bank bank) {
  this.bank = bank;
}

private PrintStream stream;

public void setStream(PrintStream stream) {
  this.stream = stream;
}

/* 
Modify System.out.println() to stream.println(), System.out.println() to stream.println().
*/

//..omit..

public static void main(String[] args) {
  ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  BankUi ui = ctx.getBean(BankUi.class);
  ui.startWork();
  ctx.close();
}

Create src/main/resources folder. (This is also the Maven project directory) Copy logback.xml in Logging and paste it into resources folder. Create an applicationContext.xml in the resources folder.

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
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="bankUi" class="net.java_school.bank.BankUi">
        <property name="stream" value="#{T(System).out}" />
        <property name="bank" ref="myBank" />
    </bean>
    
    <bean id="myBank" class="net.java_school.bank.MyBank">
        <property name="dao" ref="myBankDao" />
    </bean>

    <bean id="myBankDao" class="net.java_school.bank.MyBankDao">
    </bean>

</beans>
src
└── main
    └── resources
        ├── logback.xml
        └── applicationContext.xml

compile

C:\ Command Prompt
mvn clean compile

run

C:\ Command Prompt
mvn exec:java -Dexec.mainClass=net.java_school.bank.BankUi

Set up the project in Eclipse

Start Eclipse. (It does not matter where your workspace is) In the Project Explorer view, use the right mouse button to display the context menu. Import the JavaBank project into Eclipse as shown below.

Open Import menu in context menu

Import the JavaBank project

It would help if you synchronize Eclipse with pom.xml. With the project selected in the Package Explorer, open the context menu with the right mouse button. Select Maven, then Update Project Configuration. Whenever pom.xml changes afterwards, you should synchronize Eclipse with it again.

JavaConfig

It is possible to make beans configuration with Java classes instead of XML files nowdays. You can write beans configuration classes using @Configuration and @Bean annotations. In beans configuration classes, the method name annotated with @Bean becomes a bean object.

Create a bean configuration class as follows:

BankConfig.java
package net.java_school.bank;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BankConfig {
  
  @Bean
  public BankDao myBankDao() {
    return new MyBankDao();
  }
  
  @Bean
  public Bank myBank() {
    Bank bank = new MyBank();
    bank.setDao(myBankDao());
    return bank;
  }
  
  @Bean
  public BankUi bankUi() {
    BankUi ui = new BankUi();
    ui.setBank(myBank());
    ui.setStream(System.out);
    return ui;
  }
}

Modify the main method of the BankUi class as shown below.

BankUi.java
//the following import statement is added
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

//..omit..

public static void main(String[] args) {
  //ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BankConfig.class);
  BankUi ui = ctx.getBean(BankUi.class);
  ui.startWork();
  ctx.close();
}

Final Source: https://github.com/kimjonghoon/di

References