Java Web simple mall project (4)

Source: Internet
Author: User

Java Web simple mall project (4)

Next, I went to the javaWEB simple mall project (III), which learned how to use the reflection-based factory model and java dependency injection in the project.

1. java reflection

The JAVA reflection mechanism is in the running state. For any class, all attributes and methods of this class can be known. For any object, can call any of its methods and attributes. This kind of information obtained dynamically and the function of dynamically calling methods of objects is called the reflection mechanism of java language.
It is not as popular as before.NewCreate an object. Now, you can create an object using the qualified name of the class.

1. Get objects through reflection

The program creates a User instance using the complete qualified name of the class, which is the reflection

Public static void main (String [] args) {String str = "com. model. user "; // The qualified name of the Class. try {Class clz = Class. forName (str); // obtain the Class Object User user = (User) clz of the Class. newInstance (); // obtain the instance User of the user through the Class object. setUsername ("Admin"); System. out. println (user. getUsername ();} catch (ClassNotFoundException e) {e. printStackTrace ();} catch (InstantiationException e) {e. printStackTrace ();} catch (IllegalAccessException e) {e. printStackTrace ();}}
2. Call class methods through reflection

The reflection-based call Method mainly uses the invoke () Method of the Method class. The advantage of this is that the information to be called and strings can be written in the configuration file, then you can directly modify the modification in the configuration file, which is too convenient for later maintenance.

Public static void main (String [] args) {String str = "com. model. user "; // The qualified name of the Class String method =" setUsername "; try {Class clz = Class. forName (str); // obtain the Class Object User u = (User) clz of the Class. newInstance ();/*** getMethod can be used to obtain class methods. The first parameter is the Method name, and the second parameter is the Method parameter. The parameter */Method method1 = clz can be infinitely added. getMethod (method, String. class);/*** this method can be executed through invoke (). Parameter 1 is the object for executing this method, and parameter 2 is the method parameter */method1.invoke (u, "admin"); System. out. println (u. getUsername ();} catch (ClassNotFoundException e) {e. printStackTrace ();} catch (InstantiationException e) {e. printStackTrace ();} catch (IllegalAccessException e) {e. printStackTrace ();} catch (NoSuchMethodException e) {e. printStackTrace ();} catch (InvocationTargetException e) {e. printStackTrace ();}}
Ii. configuration file-based factory Model

Before talking about the factory model, let's talk about the OCP (open closed Principle) Principle. The Principle of open and closed is translated, meaning that the project should be open to expansion and closed to modification, that is, to achieve the minimum modification and complete the desired changes.

1. Simple factory Model

In the com. dao package, each entity has a corresponding DAO. If there are many entities, a factory for creating DAO is required for DAO management, as shown in the following example.

Import com. dao. addressDao; import com. dao. userDao;/*** Created by nl101 on 2016/2/26. */public class DAOFactory {// get UserDao public static UserDao getUserDao () {return new UserDao () ;}// get AddressDao public static AddressDao getAddressDao () {return new AddressDao ();}}

The only use is to unify Dao. When it is used, the world DAOFactory. getUserDao () can be used.
Disadvantage: If you change the database or Dao, You need to modify the corresponding method here.

2. Factory method mode

In the factory method mode, an abstract parent class defines a public interface, and the subclass is responsible for generating specific objects. The purpose of this mode is to delay the class instantiation operation to the subclass.

First, define the abstract parent interface

import com.dao.AddressDao;import com.dao.UserDao;/** * Created by nl101 on 2016/2/26. */public interface AbstractFactory {    public UserDao createUserDao();    public AddressDao createAddressDao();}

Then define the subclass that implements the specific method

Import com. dao. addressDao; import com. dao. userDao;/*** Created by nl101 on 2016/2/26. */public class MysqlDAOFactory implements AbstractFactory {/*** specific factory for Singleton design */private static AbstractFactory factory = new MysqlDAOFactory (); private DAOFactory () {} public static AbstractFactory getInstance () {return factory;} // get UserDao @ Override public UserDao createUserDao () {return new UserDao ();} // obtain AddressDao @ Override public AddressDao createAddressDao () {return new AddressDao ();}}

OracleDAOFactory can also be used, and their methods are defined by the parent interface. They are only responsible for implementing specific methods.
Disadvantages: it is still troublesome to modify the code, and the call requires MysqlDAOFactory. getInstance (). createUserDao (), which is too long.

3. configuration file-based factory

Based on the configuration file, we write some parameters to the configuration file. A Class reads the configuration file information and creates the DAO.

1.First, we need to create the properties file, which stores the qualified name of dao.

 

Dao. properties

userdao = com.dao.UserDaoaddressdao = com.dao.AddressDao

2.Create an abstract factory. There is a common DAO creation method in the factory.

public interface AbstractFactory {    public Object createDao(String name);}

3.Create peopertiesUtil to easily read the configuration file

Import java. io. IOException; import java. util. properties;/*** Created by nl101 on 2016/2/26. */public class PropertiesUtil {public static Properties daoProperties = null;/*** get dao configuration file * @ return */public static Properties getDaoPro () {// if it has been created, if (daoProperties! = Null) {return daoProperties;} daoProperties = new Properties (); try {daoProperties. load (PropertiesUtil. class. getClassLoader (). getResourceAsStream ("dao. properties "); // load the configuration file} catch (IOException e) {System. out. println ("dao configuration file not found"); e. printStackTrace ();} return daoProperties ;}}

4.Create a specific factory and obtain the corresponding DAO entity class by using the input name value and reflection.

Public class PropertiesFactory implements AbstractFactory {/*** first implement Singleton mode for the factory * @ return */private static AbstractFactory factory = new PropertiesFactory (); private PropertiesFactory () {} public static AbstractFactory getInstance () {return factory ;} /*** method for implementing the parent interface * @ param name the dao name to be created * @ return the dao created */@ Override public Object createDao (String name) {Properties properties = PropertiesUtil. getDaoPro (); String daoName = properties. getProperty (name); // get the qualified name Object obj = null for the dao to be created; // the container that carries the created Object try {Class clz = Class. forName (daoName); obj = clz. newInstance ();} catch (ClassNotFoundException e) {e. printStackTrace ();} catch (InstantiationException e) {e. printStackTrace ();} catch (IllegalAccessException e) {e. printStackTrace ();} return obj ;}}

5.For specific factory optimization, we can store the newly created dao object. When calling it, we first determine whether it has been created. If it has already been created, it will return. Therefore, we naturally think of the Map set of key-value pairs.

Import com. util. propertiesUtil; import java. util. hashMap; import java. util. map; import java. util. properties;/*** Created by nl101 on 2016/2/26. */public class PropertiesFactory implements AbstractFactory {/*** first implements the singleton mode for the factory * @ return */private static AbstractFactory factory = new PropertiesFactory (); private PropertiesFactory () {} public static AbstractFactory getInstance () {return factory;} private Map
  
   
Maps = new HashMap <> (); /*** method for implementing the parent interface * @ param name the dao name to be created * @ return the dao created */@ Override public Object createDao (String name) {// determines whether a map has been created. if yes, if (maps. containsKey (name) {return maps. get (name) ;}properties Properties = PropertiesUtil. getDaoPro (); String daoName = properties. getProperty (name); // get the qualified name Object obj = null for the dao to be created; // the container that carries the created Object try {Class clz = Class. forName (daoName); // load class obj = clz. newInstance (); // obtain instance maps. put (name, obj); // saved to map} catch (ClassNotFoundException e) {e. printStackTrace ();} catch (InstantiationException e) {e. printStackTrace ();} catch (IllegalAccessException e) {e. printStackTrace ();} return obj ;}}
  

Call the following method:

UserDao userDao = (UserDao) PropertiesFactory.getInstance().createDao("userdao");

Is it still troublesome to call the service? If you want to write it for so long, don't worry. The following dependency injection is used to solve this problem.

In this way, the configuration-based factory mode is perfect. If you want to change DAO, you only need to modify the lower limit name in the configuration file, which is very convenient.

Iii. java dependency Injection

Why is "dependency injection": All Java applications are composed of collaborative objects. We call this cooperative relationship dependency. If component A calls the method of component B, we can say that component A depends on Component B. The instance created by the system is called by the caller, or the system injects the instance into the caller.

1. Dependency injection setXXX () method

We used the UserDao class in AddressDao.UserDao userDao = (UserDao) PropertiesFactory.getInstance().createDao("userdao");For such a complex method, through dependency injection, we canCreate this classInitialize this object

1. First, we need to write the set and get methods for the class that requires dependency injection. here we need to set userDao in AddressDao.
The so-called dependency injection is to call the set Method to assign values to userDao during class initialization.

/*** Assign values through dependency injection */private UserDao userDao; public UserDao getUserDao () {return userDao;} public void setUserDao (UserDao userDao) {this. userDao = userDao ;}

2. For convenience, write a DaoUtil code to store dependency injection.

Import com. dao. propertiesFactory; import java. lang. reflect. invocationTargetException; import java. lang. reflect. method;/*** Created by nl101 on 2016/2/26. */public class DaoUtil {/*** dao dependency Injection Method * @ param obj */public static void daoInject (Object obj) {// obtain the Method of the current class, excluding the inherited Method [] methods = obj. getClass (). getDeclaredMethods (); try {// filter the setXXX Method for (method: methods) for the Method {// determine whether to start with set if (method. getName (). startsWith ("set") {// intercept the String after the set and the properties correspond to the String mm = method. getName (). substring (3); // obtain the Instance Object o = PropertiesFactory. getInstance (). createDao (mm); // call the set method to set the method. invoke (obj, o) ;}} catch (IllegalAccessException e) {e. printStackTrace ();} catch (InvocationTargetException e) {e. printStackTrace ();}}}

3. we know that all Dao has a parent class, BaseDao. When we create a Dao, we will first execute the constructor of the parent class, therefore, we can call the dependency injection method in the parent class method.

/*** Call the dependency Injection Method */public BaseDao () {DaoUtil. daoInject (this );}

In this way, the userDao variable can be initialized when AddressDao is created. However, if AddressDao has other set methods, the program reports an error because the corresponding data cannot be found in the configuration file.

2. Use Annotation to optimize Injection

What is Annotation? Is the @ symbol code before the method, as shown in figure

Therefore, we can create our own Annotation: Dao. The desired effect is as follows:

Use setXXX () to inject UserDao when @ Dao ("UserDao") does not contain parameters.

1. Create your own Annotation. From the code, you can see that the Annotation ID is @ interface.

Import java. lang. annotation. retention; import java. lang. annotation. retentionPolicy;/*** adds this declaration, indicating that the current Annotation is executed */@ Retention (RetentionPolicy. RUNTIME) public @ interface Dao {String value () default "";}

Value () indicates its value. The default value is null. You can also customize other values, suchString abc() default ""

2. Using Annotation is easy to use. Just add an identifier to the code to be injected.

    @Dao("UserDao")    public void setUserDao(UserDao userDao) {        this.userDao = userDao;    }

3. Modify the injection code to implement the logic described above

Package com. util; import com. dao. propertiesFactory; import com. model. dao; import java. lang. reflect. invocationTargetException; import java. lang. reflect. method;/*** Created by nl101 on 2016/2/26. */public class DaoUtil {/*** dao dependency Injection Method * @ param obj */public static void daoInject (Object obj) {// obtain the Method of the current class, excluding the inherited Method [] methods = obj. getClass (). getDeclaredMethods (); try {// filter the setXXX Method for (method: methods) {// if Dao Annotation exists, process if (Method. isAnnotationPresent (Dao. class) {// obtain the current Anonotation Dao = method. getDeclaredAnnotation (Dao. class); // obtain its value String name = dao. value (); // if the value is null, the character after the set is truncated as the value if (name = null | name. equals ("") {name = method. getName (). substring (3);} // obtain the Instance Object o = PropertiesFactory. getInstance (). createDao (name); // call the set method to set the method. invoke (obj, o) ;}} catch (IllegalAccessException e) {e. printStackTrace ();} catch (InvocationTargetException e) {e. printStackTrace ();}}}

It is found that the data is successfully stored through running, which solves the shortcomings of setXXX ().

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.