Programming AOP for Facets

Source: Internet
Author: User

facet-oriented Programming (AOP)

Aspect Oriented Programming

can be done byPre-compilationSquare-and run-timeDynamic Agentimplementation without modifying theSource Codea technique for adding functionality dynamically and uniformly to a program. AOP is actually GoF The continuation of design patterns, the design pattern of the tireless pursuit of the caller and the callee between the decoupling , increase the flexibility and scalability of your code, AOP can be said to be a realization of this goal.

Key Features

logging, performance statistics, security control, transaction processing, Exception Handling wait

Main intentions

logging, performance statistics, security control, transaction processing, Exception Handling Such code is separated from the business logic code, and through the separation of these behaviors, we want to be able to separate them into non-instructional methods of business logic, and then change these behaviors without affecting the code of the business logic.


Case-Transaction Management


annotation mode, defining transaction switch markers

@Retention (retentionpolicy.runtime) @Target (elementtype.method) public @interface Tran {}


Write a custom annotation on the method that needs to open the transaction

Public interface UserService extends service{/** * Registered user * @param user encapsulates the Userbean */@Tranvoid Regist


Service Implementation Class

Public class userserviceimpl implements userservice {    private  userdao dao = basicfactory.getfactory (). Getdao (Userdao.class);     Public void regist (User user)  {    try{         //1. Verify that the user name already exists         if (Dao.finduserbyname ( User.getusername ())!=null) {            throw  New runtimeexception ("User name already exists!!");         }        //2. Call the method in DAO to add the user to the database         user.setrole ("user");         user.setstate (0);         user.setactivecode ( Uuid.randomuuid (). toString ());         dao.adduser (user);         //3. Sending an activation message         properties  prop = new properties ();         prop.setproperty ( "Mail.transport.protocol",  "SMTP");         prop.setproperty (" Mail.smtp.host ", " "localhost");         prop.setproperty (" Mail.smtp.auth ", " true ");         prop.setproperty (" Mail.debug ",   "true");        session session =  Session.getinstance (prop);         message msg = new  mimemessage (session);         msg.setfrom (new  InternetAddress ("[email protected]");         msg.setrecipient ( Recipienttype.to, new internetaddress (User.getemail ()),         msg.setsubject (User.getusername () + ", activation Mail from estore");         msg.settext (User.getusername () + ", click on the link below to activate the account, if not click Please copy to the browser address bar access: HTTP ://www.estore.com/activeservlet?activecode= "+user.getactivecode ());         transport trans = session.gettransport ();         Trans.connect ("AA",  "123");         trans.sendmessage (msg,  Msg.getallrecipients ());    }catch  (exception e)  {         e.printstacktrace ();         throw new  runtimeexception (e);         }    }}


Transaction management tool class, transform the data source, determine whether to open the transaction

Public class transactionmanager {    private transactionmanager ()  {    }    //--data source, this data source is the only one in the entire program     private  static datasource source = new combopooleddatasource ();     --whether to open the tag of the transaction     private static threadlocal<boolean> istran_local  = new ThreadLocal<Boolean> () {     @Override      Protected boolean initialvalue ()  {        return  false;//--first false, indicating that the transaction is not turned on by default     }    };    //-- Save the proxy connection for the real connection, and change the Close method     private static ThreadLocal<Connection>  Proxyconn_local = new threadlocal<connection> () {};    //--Save the real connection     private&nbsP;static threadlocal<connection> realconn_local = new threadlocal<connection > () {};    /**     *  How to open a transaction       */    public static void starttran ()  throws SQLException{     istran_local.set (TRUE);//--set transaction marked as true    final connection  Conn = source.getconnection ();//--Create a connection, all database operations in the current thread are based on this conn     Conn.setautocommit (false);//--Open transaction     realconn_local.set (conn);//--to facilitate subsequent closing of the connection, Save this connection in the current thread     //--because a transaction needs to execute multiple SQL, each SQL execution closes the connection, so that subsequent SQL is not able to execute, so this local method to transform the Close method, Make him unable to close the connection     Connection proxyConn =  (Connection)  proxy.newproxyinstance (Conn.getclass (). getClassLoader (),  conn.getclass (). Getinterfaces ()     , new  invocationhandler () {    puBlic object invoke (object proxy, method method,    object[]  args)  throws throwable {    if ("Close". Equals (Method.getname ())) {         return null;    }else{         return method.invoke (Conn, args);    }     }         proxyconn_local.set (proxyConn);     }    /**     *  Submit a transaction       */    public static void commit () {         dbutils.commitandclosequietly (Proxyconn_local.get ());    }     /**     *  Rolling back Transactions      */     public static void&nBsp;rollback () {        dbutils.rollbackandclosequietly (proxyConn_ Local.get ());    }    /**     *  This method should do :     *  If a transaction is not turned on, the most common data source is returned      *  if a transaction is turned on, Returns a data source that has been transformed into a getconnection method, which returns the same open transaction connection     *  each time @return       *  @throws  SQLException      */     public static datasource getsource ()  throws SQLException{     if (Istran_local.get ()) {//--If a transaction is turned on, the datasource of the transformation is returned, and the getconnection of the same open transaction is returned for each call to conn     return  (DataSource)  proxy.newproxyinstance (Source.getclass (). getClassLoader (),  source.getclass (). Getinterfaces ()     ,new invocationhandler () {     public object invoke (OBject proxy, method method,    object[] args)  throws  Throwable {    if ("getconnection". Equals (Method.getname ())) {     Return proxyconn_local.get ();    }else{         return method.invoke (Source, args);    }    }     });     }else{//--does not open a transaction, return to the normal data source          return source;    }    }    /**      *  Release Resources       */    public  static void release () {    dbutils.closequietly (Realconn_local.get ());//-- The previous connection was not closed at the time of release to really close the connection     realconn_local.remove ();     proxyconn_ Local.remove ();      istran_local.remove ();     }} 



Service,dao's Factory class

Generate service agents, based on annotations to determine what to do before and after the service method executes

public class basicfactory {    private static basicfactory  Factory = new basicfactory ();    private static properties  Prop = null;    private basicfactory () {}    static{         try {             prop = new properties ();             prop.load (New filereader (BasicFactory.class.getClassLoader () getresource (" Config.properties "). GetPath ());        } catch  (Exception  e)  {            e.printstacktrace ();             throw new runtimeexception (E );          }    }    public static basicfactory  getfactory () {        return factory;     }         /**     *  Get Service methods      */     @SuppressWarnings ("unchecked")      public <t extends service> t getservice (Class<T> clazz) {     try{        //--create a specific service   based on the configuration file       string infname = clazz.getsimplename ();         string implname = prop.getproperty (InfName);         final T service =  (T)  class.forname (implname). Newinstance ();          //--in order to implement AOP, generate service proxies, based on annotations to determine what to do before and after the service method executes, such as: Transaction management/logging/fine-grained permission control ....         T proxyService =   (T)  proxy.newproxyinstance ( Service.getclass (). getClassLoader (),  service.getclass (). Getinterfaces ()           , new invocationhandler () {        // Control transaction         public object invoke According to annotations (Object proxy,  method method,object[] args)  throws Throwable {         if (Method.isannotationpresent (Tran.class)) {//If there is an annotation, manage the transaction:          try{             Transactionmanager.starttran ();//--Open Transaction              object obj = method.invoke(Service, args);//--Real Execution Method              Transactionmanager.commit ();//--COMMIT TRANSACTION              return obj;            }catch  ( Invocationtargetexception e)  {                 transactionmanager.rollback ();//--ROLLBACK TRANSACTION                  throw new runtimeexception ( E.gettargetexception ());             } catch   (exception e)  {                 transactionmanager.rollback ();//--ROLLBACK TRANSACTION                  throw nEw runtimeexception (e);             }finally{                  Transactionmanager.release ();//--release resources             }         }else{//without annotations, do not manage transactions, execute methods directly              return method.invoke (Service, args);           }        }      });                       return proxyService;  }catch  (Exception e)  {            e.printstacktrace ();         &nBsp;   throw new runtimeexception (e);             }        }         /**         *  ways to get DAO           */        public <t extends  dao> t getdao (Class<t> clazz) {         Try{        string infname = clazz.getsimplename ();         string implname = prop.getproperty (InfName);         return  (T)  class.forname (implname). newinstance ();     }catch  (exception e)  {     e.printstacktrace () ;       throw new runtimeexception (e);     }  }} 


There's no need to think about transactions in DAO.

Public class userdaoimpl implements userdao {    public void  adduser (User user)  {        string sql =   "insert into users values (null,?,?,?,?,?,?,?, null)";         try{            QueryRunner  Runner = new queryrunner (Transactionmanager.getsource ());             runner.update (Sql,user.getusername (), User.getpassword (), User.getNickname () , User.getemail (), User.getrole (), User.getstate (), User.getactivecode ());         }catch  (exception e)  {             e.printstacktrace ();             throw  new runtimeexceptIon (E);        }    }     Public user finduserbyname (String username)  {         String sql =  "SELECT&NBSP;*&NBSP;FROM&NBSP;USERS&NBSP;WHERE&NBSP;USERNAME&NBSP;=&NBSP;?";         try{             queryrunner runner = new queryrunner (Transactionmanager.getsource ());             return runner.query (sql, new  BeanHandler<User> (User.class), username);         }catch   (exception e)  {             E.printstacktrace ();             throw new  runtimeexception (e);         }    }} 


Programming AOP for Facets

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.